我有以下代码,它有一个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”的内存吗?
答案 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
类似于内存分配步骤的逆序。