Home > Software engineering >  Pointers in structure with dynamic memory allocation
Pointers in structure with dynamic memory allocation

Time:12-23

I am attempting to create a structure (2nd) in a structure (1st) with dynamic memory allocation. For the sequence of steps below (case 1), where I call malloc for a pointer to the 2nd structure before calling realloc for the 1st structure, I see garbage when printing the value of the member (str[0].a1) in the first structure. If I place the same realloc code before malloc (case 2), there are no issues.

#include<stdio.h>
#include<stdlib.h>

typedef struct string2_t {
    int a2;
} string2;

typedef struct string1_t {
    int a1;
    string2 * b;
} string1;


string1 * str = NULL;
int size = 0;

string1 test(int val){

    // case 2
    //str = (string1 *) realloc(str, size*sizeof(string1));

    string1 S;
    S.a1 = val;
    size  = 1;
    S.b = (string2 *) malloc(2*sizeof(string2));
    S.b[0].a2 = 11;
    S.b[1].a2 = 12;

    // case1
    str = (string1 *) realloc(str, size*sizeof(string1));
    
    return S;
}

int main() {
    size  = 1;
    str = (string1 *) malloc(size*sizeof(string1));
    str[0] = test(10);
    printf("value of a:%d\n",str[0].a1);
    str[1] = test(20);
    printf("value of a:%d\n",str[0].a1);
    return(0);
}

I can see that memory location changes for case 1, but I don't quite understand why doesn't pointer point to the right contents (str[0].a1 shows junk). I haven't returned the address of 1st structure before realloc, so I feel it should have worked. Could someone explain why it's pointing to garbage?

CodePudding user response:

As has been stated by several in the comments, lines like this cause undefined behavior:

str[0] = test(10);

The test() function reallocates str, and this is not sequenced with retrieving the address of str[0] as the location to store the result. It's very likely to be compiled as if it had been written

string1 *temp = str;
temp[0] = test(10);

temp caches the old address of str from before the realloc(), and this is invalid after the function returns.

Change your code to:

string1 temp = test(10);
str[0] = temp;

Better design would be to reorganize the code so that all maintenance of the str array is done in one place. test() should be a black box that just allocates the string1 object, while main() allocates and reallocates str when assigning to it.

  • Related