In said:
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 said:
buf = (unsigned char)*((unsigned char *)&ms) ;
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 = ((int *)ms) ;
As you can see, the correct expression is much simpler than your bit of
nonsense.
buf = '\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(struct 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 = ((int *)ms);
buf = '\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