我有一个函数可以获得char ** str_array:
char** str_array = Init();
Init分配一个char *数组,它坚持包含一个char数组。
然后我想释放内存,但我希望有一个清理功能,如下:
void FreeStr(char*** arg) {
char** str = *arg;
for (int i = 0; str[i] != '\0'; ++i) {
printf("Str %d: %s\n", i, str[i]);
free(str[i]);
}
free(str);
}
这会打印垃圾和崩溃。当for循环与声明str_array的函数相同时,for循环内部确实有效,但在调用时不会:
FreeStr(&str_array);
我很困惑为什么这不起作用。我认为额外的指针层会确保我仍指向正确的记忆。我有什么误解?
答案 0 :(得分:4)
您尚未指定Init()是返回固定长度数组还是返回以NULL结尾的数组。如果后者是这种情况,这是通常的做法,正确的代码将是:
void FreeStr(char*** arg) {
char** str = *arg;
int i;
for (i = 0; str[i] != NULL; ++i) {
printf("Str %d: %s\n", i, str[i]);
free(str[i]);
}
free(str);
*arg = NULL;
}
这样,拨打电话后
FreeStr(&str_array);
如果str_array实际上是一个malloc() - 分配的以NULL结尾的malloc()数组 - 分配的字符串,str_array变为NULL(你不希望指向释放的内存,你呢?)并且所有内存都是释放。
答案 1 :(得分:3)
不需要额外的间接层。将您的功能定义为:
void FreeStr(char** arg)
并称之为:
FreeStr(str_array);
此外,str[i] != '\0'
不是测试空指针的好方法。你应该做str[i] != NULL
。所以你的功能应该是这样的:
void FreeStr(char** str) {
for (int i = 0; str[i] != NULL; ++i) {
printf("Str %d: %s\n", i, str[i]);
free(str[i]);
}
free(str);
}