weird behavior w/ compiler?

Discussion in 'Mac Programming' started by wala, Jul 7, 2006.

  1. macrumors member

    Joined:
    Jun 3, 2005
    #1
    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?
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    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...
     
  3. thread starter macrumors member

    Joined:
    Jun 3, 2005
    #3
    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.
     
  4. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    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.
     
  5. thread starter macrumors member

    Joined:
    Jun 3, 2005
    #5
    Thanks. I feel kinda dumb.
    Where can I find OS X sizeof() tables for future reference?
     
  6. macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #6
    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.
     
  7. thread starter macrumors member

    Joined:
    Jun 3, 2005
    #7
    I know that, but I was wondering if they are listed anywhere.
     
  8. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    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...
     

Share This Page