Thread: Structs and arrays - overview and help neede

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    7

    Structs and arrays - overview and help neede

    Hi, in my phase of (re)learning C, I'm often facing problems with arrays and structures (and pointers).
    This is a little test I wrote.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct {
        char name[10];
    } man;
    
    int main (int argc, const char * argv[]) {
        int i;
        man john;
        strcpy(john.name, "john");
    
        // array of structures
        man men[10];
        strcpy(men[3].name, "john");
        printf("*** %s ***\n", men[3].name);
    
        // dynamic array of structures
        man *men2;
        men2 = malloc(10 * sizeof(man));
        strcpy(men2[3].name, "john");
        printf("*** %s ***\n", men2[3].name);
    
        // multidimensional array of structures
        man men3[10][10];
        strcpy(men3[3][3].name, "john");
        printf("*** %s ***\n", men3[3][3].name);
    
        // dynamic multidimensional array of structures
        man **men4;
        men4 = malloc(10 * sizeof(man*));
        for (i = 0; i < 10; i++)
            men4[i] = malloc(10 * sizeof(man*));
        strcpy(men4[3][3].name, "john");
        printf("*** %s ***\n", men4[3][3].name);
    
        // array of pointer to structure
        man *men5[10];
        men5[3] = &john;
        printf("*** %s ***\n", men5[3]->name);
    
        // dynamic array of pointers to structure
        man **men6;
        men6 = malloc(10 * sizeof(*men6));
        men6[3] = &john;
        printf("*** %s ***\n", men6[3]->name);   
    
        // dynamic multidimensional array of pointers to structures
        /* ? */
    
        return 0;
    }
    Can you:
    1. tell me if all is correct
    2. explain why in men4 i use sizeof(man*) by in men6 it is sizeof(*men6)
    3. explain how to make a dynamic multidimensional array of pointers to structures (last point)
    4. explain me men4? it works, but is seems to me more of an array of pointers to structure than a multidimensional array of structures!

    Thanks in advance.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    1)
    The man4 is incorrect.
    Code:
        man **men4;
        men4 = malloc(10 * sizeof(man*));
        for (i = 0; i < 10; i++)
            men4[i] = malloc(10 * sizeof(man));
        strcpy(men4[3][3].name, "john");
        printf("*** %s ***\n", men4[3][3].name);
    You should allocate 10 man structures, not 10 pointers to them (marked in red).

    2) They are the same. Sizeof would look at the type of men6 and see man**, and then you dereference the type, so you get man*. So they are the same, only the second is more robust, since if you should change the type of man6, it will still work correctly, as opposed to the first where you have to change the sizeof too.

    3) It shouldn't be difficult. All you do is allocate 10 pointers to man (man*).
    Then to each of these pointers, you assign the address of a struct.
    I really think the example says it all. What part confuses you?

    4) The first pointer to pointer points to an array of 10 pointers.
    All of these pointers point to 10 structures each.
    Compare to an array:
    The array itself "points" (or holds) 10 elements.
    Each element holds another 10 elements.

    You could see it as boxes.
    man array[10][10];
    The array contains 10 big boxes. And inside those 10 boxes are 10 smaller boxes. If we would add another dimension, then those smaller boxes would contain yet smaller boxes, and so on.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    7
    thank you very much, elysia, it helped a lot!

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    7
    is this the correct way of doing the last point?
    Code:
    	// dynamic multidimensional array of pointers to structures
    	man ***men7;
    	men7 = malloc(10 * sizeof(man**));
    	for (i = 0; i < 10; i++)
    		men7[i] = malloc(10 * sizeof(man*));
    	men7[3][3] = &john;
    	printf("*** %s ***\n", men7[3][3]->name);

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No.
    You must understand the difference between the allocation - ie the data, and the pointer itself.
    When we allocate data, somewhere in the heaps of memory, get some some bits of storage. In order to use it, we need some data to tell us where that data lies - ie point to it.
    So we get a pointer to out allocated memory. If you replace that pointer which contains the address to that storage, you lose all access to the storage since we don't know where it exists anymore.
    In the example above, you do just that. You discard the pointer to the allocated memory on the heap and replace the address in the pointer with a new address.

    If you got all that, then do you think you can fix your example?
    Let it be a test to show that you understood all of that.
    Feel free to ask questions if you don't understand.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    7
    thanks again for your interest. i don't think i got it, by the way. the way i read the code i wrote (so that it may be easier for you to understand where i'm wrong, eventually is:

    man ***men7;

    here i declare an array [of not defined size] to an array [of not defined size] of pointers to to the struct man

    men7 = malloc(10 * sizeof(man**));

    i allocate the space for 10 pointers to pointers to man, or an array of 10 pointers to pointers to man

    for (i = 0; i < 10; i++)
    men7[i] = malloc(10 * sizeof(man*));

    each of those 10 pointers defined in the step before is allocated the space for 10 [sub] pointers to man

    men7[3][3] = &john;

    here the 4th pointer to man of the 4th pointer to pointer to man is assigned the address of man "john" defined before

    printf("*** %s ***\n", men7[3][3]->name);

    and i recall it.

    what is the flaw in my logic or understanding of pointers? thank in advance again!

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Actually, what you have done is basically a 2D-array of pointers to man, yes.
    (I didn't notice it was different from the previous example with a pointer to pointer.)
    It is correct. It was my mistake.
    I should instead say well done.

    I should note that man *** men7 is NOT an array. It's a pointer to a pointer to a pointer. A pointer is just a variable that points to a memory location and nothing more. Therefore, you can point it to the beginning of an array, or even a single value. Keep that in mind.

    And don't forget to free all that memory later!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    7
    thanks again for your help, it really helped me made some things clearer.

Popular pages Recent additions subscribe to a feed