To avoid memory leaks, we need to handle reallocating with care (more on that later). The realloc function:
void *realloc(void *ptr, size_t size)
, where
ptr
= the pointer to the original (malloc
'ed) memory block, and
size
= the new size of the memory block (in bytes).
realloc
returns the new location of the dynamically allocated memory block (which may have changed) - or NULL if the re-allocation failed! If it returns NULL, the original memory stays unchanged, so you must always use a temporary variable for the return value of realloc
.
An example will clarify this a bit (points of interest: realloc syntax is similar to malloc's (no need for extra casts etc.) and, after realloc, you need to produce the same steps for the new objects as you did after malloc):
struct st_temp **temp_struct;
temp_struct = malloc(20 * sizeof *temp_struct);
if (temp_struct == NULL) { /* handle failed malloc */ }
for (int i = 0; i < 20; ++i) {
temp_struct[i] = malloc(sizeof *temp_struct[i]);
temp_struct[i]->prod = "foo";
}
// We need more space ... remember to use a temporary variable
struct st_temp **tmp;
tmp = realloc(temp_struct, 30 * sizeof *temp_struct);
if (tmp == NULL) {
// handle failed realloc, temp_struct is unchanged
} else {
// everything went ok, update the original pointer (temp_struct)
temp_struct = tmp;
}
for (int i = 20; i < 30; ++i) { // notice the indexing, [20..30)
// NOTICE: the realloc allocated more space for pointers
// we still need to allocate space for each new object
temp_struct[i] = malloc(sizeof *temp_struct[i]);
temp_struct[i]->prod = "bar";
}
// temp_struct now "holds" 30 temp_struct objects
// ...
// and always do remember, in the end
for (int i = 0; i < 30; ++i)
free(temp_struct[i]);
free(temp_struct);
Do note, that this is not really an array of structs, but more an array of pointers to structs - or even an array of arrays of struct if you wish. In the last case, each sub-array would be of length 1 (since we only allocate space for one struct).