在C中正确执行free()的方法

时间:2014-03-20 03:21:57

标签: c malloc free

我有以下代码,它有一个struct数组。每个数组元素都有一个字符串副本。我的问题是在完成所有事情之后做free()的正确方法是什么:

  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 }

将在执行结束时释放分配给每个“val”的内存吗?

2 个答案:

答案 0 :(得分:3)

您需要释放val字段,因为strdup会生成动态分配的字符串的新副本。

为了避免很多堆分配,如果你有一个字符串长度的上限,那么就不需要使用strdup。只需在struct本身内声明一个静态char数组:

const size_t MAX_LENGTH = 32;

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

并使用strncpy复制内容。

此外,没有必要将malloc返回指针转换为指定的类型,因为在C中void*可以转换为其他类型,而不需要显式向下转换(在C ++中不是这样) )。

答案 1 :(得分:1)

请记住,一旦释放了指针(地址),就无法通过该地址访问内存。 strdup()为每个test_array[i].val分配内存(以及复制字符串),所以先在循环中释放它,然后释放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

类似于内存分配步骤的逆序。