Question

I have the following code that has an array of struct. Each array element has a copy of string. My question is what is correct way of doing free() after everything is done:

  1 #include <string.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4
  5 typedef struct testStruct {
  6         char *val;
  7         int index;
  8 } testStruct;
  9
 10
 11 int main()
 12 {
 13         char *value = "hello world";
 14         int NMAX = 10;
 15         testStruct *test_array = (testStruct *) malloc(NMAX * sizeof(testStruct));
 16
 17         int i;
 18         for (i = 0; i < NMAX; i++)
 19         {
 20                 test_array[i].val = strdup(value);
 21                 test_array[i].index = i;
 22
 23                 printf("added %d \n", i);
 24         }
 25
 26         for (i = 0; i < NMAX; i++)
 27         {
 28 //              free(test_array[i].val);  /* is it okay not to free the val field? */
 29         }
 30         free(test_array);         /* only do this free() on the entire array */
 31
 32 }

will the memory allocated to each "val" released at the end of the execution?

Was it helpful?

Solution

You need to free the val field, because strdup generates a new copy of the string which is dynamically allocated.

To avoid many heap allocations, if you have an upper bound to the string length, then there is no need to use strdup. Just declare a static char array inside the struct itself:

const size_t MAX_LENGTH = 32;

typedef struct TestStruct
{
  char val[MAX_LENGTH];
  ..
}

and use strncpy to copy the content.

In addition there's no need to cast malloc returned pointer to the specified type, as in C a void* is convertible to other types without the need of an explicit downcast (this is not true in C++).

OTHER TIPS

Remember once you have free a pointer(address) you can't access memory via that address. strdup() allocate memory(and also copy string) for each test_array[i].val, so first free it in a loop then free test_array:

for (i = 0; i < NMAX; i++)
{
     free(test_array[i].val); // free memory allocated by `strdup(value);`
}
free(test_array); // free by malloc() @ line number 15

It is something like reverse order of memory allocation steps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top