Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

wala

macrumors member
Original poster
Jun 3, 2005
46
0
Has anyone ever encountered this before in C:
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
        char **strings;
        int i;
        strings = (char **) malloc(65);
        strings[0] = (char *) malloc(strlen("string") + 1);
        strcpy(strings[0], "string");
        for (i = 1; i < 65; i++)
                strings[i] = NULL;
        printf("%s\n", strings[0]);
        free(strings[0]);
        free(strings);
        return 0;
}

When I run the above code, a blank line is printed! Is something wrong?

EDIT: I probably shouldn't be blaming this on the compiler (Apple's gcc). It's probably just my poor coding skills. Still, what is happening?
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
If you take out the for loop you get the expected behaviour.

So we ask ourselves why?

Well what have we done? We've allocated an array of 65 elements each of which is big enough to hold a pointer to a character array. Then we malloc some more space for out string at store the result into the first element of our array. And all is good.

Then we string copy "string" into memory starting with the first element of our array. Note the first element, not the memory pointed to by the first element.

The same for the print.

OK, more thought, I'm not totally convinced by more own explanation. All I know is removing the loop makes it work...
 

wala

macrumors member
Original poster
Jun 3, 2005
46
0
When strings[21] and only strings[21] is set to NULL, the output is just "stri".
There is no output when only strings[20] is set to NULL.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
OK. It's really simple.

malloc(65) creates a 65 byte array of memory. A char* pointer is, of course, 32 bits or 4 bytes. So you are totally messing with the string when you start writing NULL at strings[1].

If you change malloc(65) to malloc(65*sizeof(char*)) then it's good.
 

wala

macrumors member
Original poster
Jun 3, 2005
46
0
Thanks. I feel kinda dumb.
Where can I find OS X sizeof() tables for future reference?
 

iSee

macrumors 68040
Oct 25, 2004
3,540
272
wala said:
Thanks. I feel kinda dumb.
Where can I find OS X sizeof() tables for future reference?

You don't need tables because the compiler knows. You just use sizeof(sometype). So, to allocate 65 values of type long, you would use:

mylongs = (long *) malloc(65 * sizeof(long));

or 22 floats:

myfloats = (float *) malloc(22 * sizeof(float));

or 17 char*'s:

strings = (char**) malloc(17 * sizeof(char*));

It works for any type, including structs.
 

wala

macrumors member
Original poster
Jun 3, 2005
46
0
I know that, but I was wondering if they are listed anywhere.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
wala said:
I know that, but I was wondering if they are listed anywhere.

They are decided at compile time. For example if you were to compile in 64bit mode (which you should be able to do for a pure C command line executable I think) pointers would be 64bits instead of 32bits.

You could write a program to print out the sizeof all the basic types...
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.