Thread: Accessing Nested double pointer structures using malloc and free

  1. #1
    Registered User
    Join Date
    Oct 2015
    Posts
    2

    Accessing Nested double pointer structures using malloc and free

    The code is as below for accessing the nested double pointer structure. I am facing segmentation faults.
    Can any one let me know how i should be accessing the structure elements.

    code is below:
    Code:
    struct x {
            int roll;
            int class;
    };
    struct y {
            int year;
            struct arr {
                    struct x **array;
                    int count;
            }*arr;
    
    };
    
    struct z {
            struct arr1{
                    struct y **array;
                    int cnt;
            }*arr1;
    };
    
    int main(void) {
            int i,j;
            struct arr a1;
            struct arr1 a2;
            struct z aka;
    
            aka.arr1 = &a2;
            aka.arr1->cnt = 98989;
    
            aka.arr1->array = (struct y **) malloc(2 * sizeof(struct y ));
            assert(aka.arr1->array);
            for(i=0;i<2;i++) {
                    aka.arr1->array[i] = (struct y *) malloc(2 * sizeof(struct y ));
                    assert(aka.arr1->array[i]);
                    aka.arr1->array[i]->year = 2014;
    
                    aka.arr1->array[i]->arr = &a1;
                    aka.arr1->array[i]->arr->array = (struct x **) malloc(2 * sizeof(struct x));
                    assert(aka.arr1->array[i]->arr->array);
                    for(j=0;j<2;j++) {
                            aka.arr1->array[i]->arr->array[j] = (struct x *) malloc(2 * sizeof(struct x));
                            assert(aka.arr1->array[i]->arr->array[j]);
                            aka.arr1->array[i]->arr->array[j]->roll = 12345;
                            aka.arr1->array[i]->arr->array[j]->class = 98765;
                    }
            }
            free(aka.arr1->array[0]->arr->array[0]);
            free(aka.arr1->array[0]->arr->array[1]);
            free(aka.arr1->array[1]->arr->array[0]);
            free(aka.arr1->array[1]->arr->array[1]);
            free(aka.arr1->array[0]->arr->array);
    //      free(aka.arr1->array[1]->arr->array); => Segmentation fault at it this place if i enable and memory leak as well.
            free(aka.arr1->array[0]);
            free(aka.arr1->array[1]);
            free(aka.arr1->array);
            return 0;
    }
    I checked with the valgrind tool for memory leaks.
    Can anyone help and let me know what needs to be done.

    Thanks,
    Lokesh

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,323
    This looks wrong:
    Code:
    aka.arr1->array = (struct y **) malloc(2 * sizeof(struct y ));
    I suggest:
    Code:
    aka.arr1->array = malloc(2 * sizeof(aka.arr1->array[0]));
    Likewise, while this looks correct:
    Code:
    aka.arr1->array[i] = (struct y *) malloc(2 * sizeof(struct y ));
    It would be less error-prone to write:
    Code:
    aka.arr1->array[i] = malloc(2 * sizeof(aka.arr1->array[i][0]));
    Anyway, overall your problem is a lack of abstraction: you should be giving these structs more descriptive names and writing functions to create, access, modify and destroy objects of these struct types.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    You have some useless struct's. As far as i can see, you can also write:
    Code:
    struct x {
        int roll;
        int class;
    };
    
    struct y {
        int year;
        struct x *array;
        int count;
    };
    
    struct z {
        struct y *array;
        int count;
    };
    I write allways a init-function and free-function for nested struct's.
    Code:
    // functions for struct x
    
    int init_struct_x (struct x **pp_struct_x, size_t count) {
    
    // if the caller give a NULL-pointer - stop!
        if (pp_struct_x == NULL) return -1;
    
    // if there is allready a struct allocated - stop!
        if (*pp_struct_x != NULL) return -1;
    
    // if the malloc fails - stop!
        if ((*pp_struct_x = malloc ( sizeof(**pp_struct_x) * count )) == NULL ) return -1;
    
    // init the member
        size_t i;
        for (i = 0 ; i < count ; i++) {
            (*pp_struct_x)->roll = 0;
            (*pp_struct_x)->class = 0;
        }
    
        return 0;
    }
    
    void free_struct_x (struct x **pp_struct_x) {
    
    // if the caller give a NULL-pointer - stop!
        if (pp_struct_x == NULL) return;
    
    // if there is no struct allocated - stop!
        if (*pp_struct_x == NULL) return;
    
        free (*pp_struct_x);
        *pp_struct_x = NULL;
    }
    
    // functions for struct y
    
    int init_struct_y (struct y **pp_struct_y, size_t count) {
    
    // if the caller give a NULL-pointer - stop!
        if (pp_struct_y == NULL) return -1;
    
    // if there is allready a struct allocated - stop!
        if (*pp_struct_y != NULL) return -1;
    
    // if the malloc fails - stop!
        if ((*pp_struct_y = malloc ( sizeof(**pp_struct_y) * count )) == NULL ) return -1;
    
    // init the member
        size_t i;
        for (i = 0 ; i < count ; i++) {
            (*pp_struct_y)->year = 0;
            (*pp_struct_y)->array = NULL;
            (*pp_struct_y)->count = 0;
        }
    
        return 0;
    }
    
    void free_struct_y (struct y **pp_struct_y) {
    
    // if the caller give a NULL-pointer - stop!
        if (pp_struct_y == NULL) return;
    
    // if there is no struct allocated - stop!
        if (*pp_struct_y == NULL) return;
    
    // check if there are sub-struct's and free it
        if ((*pp_struct_y)->array) free_struct_x ( &(*pp_struct_y)->array );
        free (*pp_struct_y);
        *pp_struct_y = NULL;
    }
    I have write this code out of my mind! Its absolutly untested!
    But i think you can see how i manage nested struct's.
    I don't know if this is best practice.
    There are other members in this forum with profesional knowledge.
    Other have classes, we are class

  4. #4
    Registered User
    Join Date
    Oct 2015
    Posts
    2
    @ laserlight
    I tried the same points as suggested by you. But Still i get memory leaks at
    aka.arr1->array[1]->arr->array

    When i try to free this part, i get segmentation fault.

    @WoodSTokk
    Yes i need to use the structures as i have posted. The idea of free and init functions looks good.
    If you can let me know on the same structure as i have posted, would be of help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. free double pointer
    By nimitzhunter in forum C Programming
    Replies: 7
    Last Post: 12-18-2010, 01:43 AM
  2. Replies: 7
    Last Post: 10-30-2010, 10:36 PM
  3. Seg fault when accessing double pointer
    By cerr in forum C Programming
    Replies: 14
    Last Post: 12-30-2009, 03:50 PM
  4. Malloc - Free giving double free or corruption error
    By andrew.bolster in forum C Programming
    Replies: 2
    Last Post: 11-02-2007, 06:22 AM
  5. malloc,free pointer question.
    By freeindy in forum C Programming
    Replies: 5
    Last Post: 10-29-2007, 10:23 AM

Tags for this Thread