How do you use realloc when you have a pointer to a pointer to a structure?

I have this array of structures, and this function takes a pointer to an array pointer. The initial size is 2, so when it reaches the size, I need to redistribute and double the size. When this code works, I get an invalid old size error from realloc. What am I doing wrong?

int PopulateArray(struct Inventory **inv, int *size, FILE *inputFile) { int count = 0; printf("address: %u\n", inv); printf("address: %u\n", **inv); int itemNumber; int quantity; float price; int month; int year; while (fscanf(inputFile, "%i %i %f %i/%i", &itemNumber, &quantity, &price, &month, &year) != EOF) { (*inv)->itemNumber = itemNumber; (*inv)->quantity = quantity; (*inv)->price = price; (*inv)->expDate.month = month; (*inv)->expDate.year = year; printf("count: %i size: %i\n", count, *size); if (count == *size - 1) { inv = realloc(inv, (*size * 2 * sizeof(struct Inventory))); *size *= 2; } inv++; count++; } return count; } 
+5
source share
3 answers

Your inv function has (presumably) the address of a pointer variable. You want to pass its value to this variable in realloc .

 *inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory))); 

For the same reason, the inv increment will not do what you expect.

Since you need to use realloc , you must use count to reference the array.

 while (fscanf(inputFile, "%i %i %f %i/%i", &itemNumber, &quantity, &price, &month, &year) != EOF) { (*inv)[count].itemNumber = itemNumber; (*inv)[count].quantity = quantity; (*inv)[count].price = price; (*inv)[count].expDate.month = month; (*inv)[count].expDate.year = year; printf("count: %i size: %i\n", count, *size); if (count == *size - 1) { *inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory))); if (*inv == NULL) { perror("realloc failed"); exit(1); } *size *= 2; } count++; } 
+4
source

The problem is due to a change in inv ( inv++; ).

You can only use realloc tags if the passed pointer is a valid allocated pointer, and not a pointer in the selected zone.

So you need to save your inv data so you can use realloc . The pointer to the current element must be another variable.

And make sure realloc does not return NULL before assigning inv back or you lose the original pointer.

It almost made me miss the biggest mistake (1 error hides another, classic): you pass a struct Inventory ** type to change the pointer, but instead you change the double pointer.

You should execute your realloc at the specified value, and not at the pointer address:

 *inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory))); 
+3
source

When you update inv from realloc() , your inv now points to the beginning of the newly modified array. So your code

  if (count == *size - 1) { inv = realloc(inv, (*size * 2 * sizeof(struct Inventory*))); *size *= 2; } inv++; 

the last inv++ will make inv efficiently for inv[1] , not inv[count] , which you probably would like to specify.

I add below because incorrect answers are supported

Sentence

 *inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory))); 

wrong.

What you are trying to do is double the array of pointers dynamically. So the correct pointer type for going to realloc here struct Inventory ** .

(You probably created the initial table pptr = malloc(sizeof(struct Inventory*) * INIT_SIZE) , so inv correct type for realloc here)

Having said that after realloc executed in your function, the original inv pointer used by the code that calls this function is no longer valid, so when you return this function, you lose the pointer to resize the array. To handle this, you must return the new value of the inv pointer of the calling function.

additional editing:

And don't forget to allocate memory for the actual struct Inventory element:

 inv[count] = malloc(sizeof(struct Inventory)); 

at the beginning of the cycle.

0
source

Source: https://habr.com/ru/post/1261221/


All Articles