473,657 Members | 2,661 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Stupid cast question

This is not homework.

I'm trying to understand why this code doesn't output "$$$$$$$\0\ n"
-- all I get is "$)\n". (I admit I'm an idiot, OK?)

#include <stdio.h>
#include <stdlib.h>

struct mystruct
{
int a, b, c, d, e, f, g ;
} ;

int
main(void)
{
int i ;
struct mystruct * ms = malloc( sizeof(struct mystruct) ) ;
unsigned char * buf = malloc( sizeof(struct mystruct) + 1 ) ;

ms->a = ms->b = ms->c = ms->d = ms->e = ms->f = ms->g = '$' ;

for ( i = 0; i < sizeof( ms ) ; i++ )
buf[i] = (unsigned char)*((unsigne d char *)&ms[i]) ;

buf[i] = '\0' ;

printf( "%s\n", buf ) ;

return 0 ;
}
Nov 13 '05 #1
5 2523
Dopey <do***@nobrains .com> wrote:
This is not homework. I'm trying to understand why this code doesn't output "$$$$$$$\0\ n"
-- all I get is "$)\n". (I admit I'm an idiot, OK?) #include <stdio.h>
#include <stdlib.h> struct mystruct
{
int a, b, c, d, e, f, g ;
} ; int
main(void)
{
int i ;
struct mystruct * ms = malloc( sizeof(struct mystruct) ) ;
unsigned char * buf = malloc( sizeof(struct mystruct) + 1 ) ;
Shouldn't you check that ms and buf aren't NULL?

ms->a = ms->b = ms->c = ms->d = ms->e = ms->f = ms->g = '$' ;

for ( i = 0; i < sizeof( ms ) ; i++ )
sizeof(ms) returns the size of the pointer, not the length of what
it points to. Use either "sizeof *ms" or sizeof(struct mystruct).
buf[i] = (unsigned char)*((unsigne d char *)&ms[i]) ;
ms isn't an array, but a pointer to a single structure (that's all
you allocated). Since you obviously try to print out the structure
in a byte by byte fashion you probably need

buf[i] = * ( ( unsigned char * ) msg + i );

to step over the memory pointed to by ms in a byte-by-byte way.

buf[i] = '\0' ;

printf( "%s\n", buf ) ;
This still won't print out "$$$$$$$\0\ n". First of all '\0' isn't a
printable character, it indicates the end of the string. Second,
the members of your mystruct are all ints, and since the size of an
int is usually larger than the one of a char you will have additional
(zero) bytes in between the '$'s (not even counting possible padding
bytes). The moment the printf() function finds one of the zero bytes
it will stop printing.
return 0 ;
}

Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Je***********@p hysik.fu-berlin.de
_ | | | | | |
| |_| | | | | | http://www.physik.fu-berlin.de/~toerring
\___/ens|_|homs|_|oe rring
Nov 13 '05 #2
In <MP************ ************@ne ws.verizon.net> Dopey <do***@nobrains .com> writes:
This is not homework.

I'm trying to understand why this code doesn't output "$$$$$$$\0\ n"
It was a good idea that you posted the expected output, because the
program is completely meaningless and we couldn't figure out how to fix
it without this piece of information.
-- all I get is "$)\n". (I admit I'm an idiot, OK?)
OK ;-)
#include <stdio.h>
#include <stdlib.h>

struct mystruct
{
int a, b, c, d, e, f, g ;
} ;

int
main(void)
{
int i ;
struct mystruct * ms = malloc( sizeof(struct mystruct) ) ;
unsigned char * buf = malloc( sizeof(struct mystruct) + 1 ) ;
The size of the buffer is incorrectly calculated: you want one byte for
each member of the struct plus one byte for the string terminator.
Assuming a non-perverse implementation, you can obtain the number of
struct members (in this particular case) with the following expression:

sizeof *ms / sizeof ms -> a

or

sizeof(struct mystruct) / sizeof(int)

The former may look more cryptical, but it doesn't require any
maintenance if you decide to change the name of the struct or the type
of its members later.

So, the correct allocation for buf is:

unsigned char * buf = malloc((sizeof *ms / sizeof ms -> a) + 1 ) ;
ms->a = ms->b = ms->c = ms->d = ms->e = ms->f = ms->g = '$' ;

for ( i = 0; i < sizeof( ms ) ; i++ )
You got the iteration count horribly wrong: sizeof ms is giving you the
size of a pointer to a structure, which is completely unrelated to the
number of members of the struct. You need exactly the same expression
as above:

for (i = 0; i < sizeof *ms / sizeof ms -> a; i++)
buf[i] = (unsigned char)*((unsigne d char *)&ms[i]) ;
This is a horrible mess. You have allocated memory for a single
struct, not for a whole array of them. What you need is to convert ms
to pointer to int and use that pointer for accessing each member of
the struct, as if you had an array of int's:

buf[i] = ((int *)ms)[i] ;

As you can see, the correct expression is much simpler than your bit of
nonsense.
buf[i] = '\0' ;

printf( "%s\n", buf ) ;

return 0 ;
}


Now, let's see what we've got:

fangorn:~/tmp 2493> cat test.c
#include <stdio.h>
#include <stdlib.h>

struct mystruct
{
int a, b, c, d, e, f, g ;
};

int main(void)
{
int i;
struct mystruct *ms = malloc(sizeof(s truct mystruct));
char *buf = malloc((sizeof *ms / sizeof ms -> a) + 1);

ms->a = ms->b = ms->c = ms->d = ms->e = ms->f = ms->g = '$';
for (i = 0; i < sizeof *ms / sizeof ms -> a; i++)
buf[i] = ((int *)ms)[i];
buf[i] = '\0';
printf("%s\n", buf);
return 0 ;
}
fangorn:~/tmp 2494> gcc -ansi -pedantic test.c
fangorn:~/tmp 2495> ./a.out
$$$$$$$

It looks like the expected output. But the program still relies on the
reasonable assumption that struct mystruct contains no padding at all.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #3
Je***********@p hysik.fu-berlin.de wrote...
Dopey <do***@nobrains .com> wrote:
This is not homework.

I'm trying to understand why this code doesn't output "$$$$$$$\0\ n"
-- all I get is "$)\n". (I admit I'm an idiot, OK?)

#include <stdio.h>
#include <stdlib.h>

struct mystruct
{
int a, b, c, d, e, f, g ;
} ;

int
main(void)
{
int i ;
struct mystruct * ms = malloc( sizeof(struct mystruct) ) ;
unsigned char * buf = malloc( sizeof(struct mystruct) + 1 ) ;


Shouldn't you check that ms and buf aren't NULL?


There's quite enough to criticize in the code without dinging me for
leaving the error checking out of the example I posted to illustrate
the problem.
Nov 13 '05 #4
Dopey <do***@nobrains .com> wrote in message news:<MP******* *************** **@news.verizon .net>...
This is not homework.
even if it was, giving it a try before asking for help
is the accepted way of doing things.

<grin> its a good thing you follow accepted ways !

I'm trying to understand why this code doesn't output "$$$$$$$\0\ n"
-- all I get is "$)\n". (I admit I'm an idiot, OK?)
great, that'll save Dan Pop the effort of admitting that you
are an idiot :-)

#include <stdio.h>
#include <stdlib.h>

struct mystruct
{
int a, b, c, d, e, f, g ;
} ;

int
main(void)
{
int i ;
struct mystruct * ms = malloc( sizeof(struct mystruct) ) ; 97**@news.veriz on.net>...
unsigned char * buf = malloc( sizeof(struct mystruct) + 1 ) ;
unsigned char * buf = malloc( sizeof(struct mystruct) + 1 ) ;
at this point, it is generally a good idea to check
that malloc returned a non-null pointer. what if the
system was out of memory ?
ms->a = ms->b = ms->c = ms->d = ms->e = ms->f = ms->g = '$' ;
ms->a = ms->b = ms->c = ms->d = ms->e = ms->f = ms->g = '$' ;
for ( i = 0; i < sizeof( ms ) ; i++ )
sizeof ( ms ) would be the size of a *pointer* to your struct.
to get the size of the actual object, you should use
sizeof (*ms);
buf[i] = (unsigned char)*((unsigne d char *)&ms[i]) ;
ms is *not* an array. it is a pointer to a single struct. I understand
what you are aiming for (i must, after all you posted the expected
output above :-), but I would recommend that you access each member
of a struct individually. the reason is because the compiler *may*
pad the struct, and accessing the struct as one block of memory is
bound to end in tears sooner or later, as you find 'gaps' in your
block of data would be filled with garbage.
uld be filled with garbage.
buf[i] = '\0' ;
'\0' ;
printf( "%s\n", buf ) ;
even if your compiler did not pad the structure, this can still
fail if sizeof (int) != sizeof (char), as printf ("%s\n", buf)
needs an array of chars, not an array of integers.

return 0 ;
}


hth

goose,
outlaw the non sc apps. makes life easier for *evryone* :-)
Nov 13 '05 #5
Dopey wrote:

Je***********@p hysik.fu-berlin.de wrote...
Dopey <do***@nobrains .com> wrote:
This is not homework.

I'm trying to understand why this code doesn't output "$$$$$$$\0\ n"
-- all I get is "$)\n". (I admit I'm an idiot, OK?)

#include <stdio.h>
#include <stdlib.h>

struct mystruct
{
int a, b, c, d, e, f, g ;
} ;

int
main(void)
{
int i ;
struct mystruct * ms = malloc( sizeof(struct mystruct) ) ;
unsigned char * buf = malloc( sizeof(struct mystruct) + 1 ) ;


Shouldn't you check that ms and buf aren't NULL?


There's quite enough to criticize in the code without dinging me for
leaving the error checking out of the example I posted to illustrate
the problem.


It would have been less effort on your part
to include error checking originally, than to answer.
That you are personally aware that error checking belongs in the code,
is good, but it is not all that matters.
Your code is out there for all to see,
and it is missing error checking.

--
pete
Nov 13 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
547
by: Richard Lee | last post by:
Hi, I have a question when I do a data type cast. the common way when we do a cast, is we know the type we want to cast to, i.e. we want to cast object to string, object xyz = "question"; (string)xyz; now we only have a type object of System.String type
119
4578
by: rhat | last post by:
I heard that beta 2 now makes ASP.NET xhtml compliant. Can anyone shed some light on what this will change and it will break stuff as converting HTML to XHTML pages DO break things. see, http://www.alistapart.com/articles/betterliving/ I read on http://msdn.microsoft.com/netframework/default.aspx?pull=/library/en-us/dnnetdep/html/netfxcompat.asp It said they changed stuff like this
15
1722
by: Christopher Benson-Manica | last post by:
If you had an unsigned int that needed to be cast to a const myClass*, would you use const myClass* a=reinterpret_cast<const myClass*>(my_val); or const myClass* a=(const myClass*)myVal; ?
5
2582
by: MC | last post by:
Hi If I have a pointer to a some structure say for example payroll_ptr where struct payroll { ... } has some members and if i use a function argument as int function_process ( (payroll_ptr) 0 , ..) does the first argument become a NULL pointer ?
2
2299
by: Lampa Dario | last post by:
Hi, where is this stupid error in this program? When I execute it, i receive a segmentation fault error. #include <stdio.h> int main(int argc, char *argv, char *env) { int i=0; int l=0; int word=0; char *querystring; querystring=malloc(sizeof(char)*100000); if (getenv("QUERY_STRING")==NULL)
3
1042
by: Bill | last post by:
I am confused why I must cast an enum to a type int if I defined the enum as follows: enum COLUMNS :int { IP=0, MSG =1 } IMHO the compiler should be able to make the conversion without requiring a cast. I am curious why the cast is required.
6
1608
by: Adam Smith | last post by:
I have posted this and similar questions repeatedly and can't even raise a single response. I am being led to believe that this then 'Must be a stupid question' although people say that there is no stupid question. Is that another for political correctness I am attempting an install of 7.4.3 on FreeBSD O/S 4.9, apparently remnants of 7.3.x are scattered around on the disk from (a) previous ports installation, causing mutex_lock/unlock,...
4
118805
by: dba_222 | last post by:
Dear Experts, Ok, I hate to ask such a seemingly dumb question, but I've already spent far too much time on this. More that I would care to admit. In Sql server, how do I simply change a character into a number?????? In Oracle, it is:
1
1095
by: Chris | last post by:
I periodically, once every week or so, get an error when trying to read an XML doc stored in cache. I get an 'object not set to a reference' I have a gut feeling it happens when the app is under strain and the moment between testing the cache and returning the cached xml doc it expires. I have read several other people have the same problem. I have seen some C# code which theoretically makes sense to me, but I don't understand the syntax...
10
1790
by: Chris Becke | last post by:
In C and in older C++ compilers, you could write code like this void a(void** pp); // declare a function that takes a pointer to a pointer-to-void. struct I {}; // some struct. I *i1,**i2; // some kinds of i. a(&i1); // this works a(i2); // this also worked. a(i1); // error: incorrect levels of indirection a(&i2); // error: incorrect levels of indirection
0
8407
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8319
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8837
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8612
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7347
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4329
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2739
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1969
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1732
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.