char **test() {
char **res = (char **)malloc(sizeof(char *) * 5);
for (int cur = 0; cur < 3; cur++) {
char *str = (char *)malloc(10);
strcpy(str, "Maneger");
res[cur] = (char *)malloc(strlen(str));
strcpy(res[cur], str);
free(str);
}
res[3] = NULL;
return res;
}
int main(int argc, char *argv[]) {
char **li = test();
//some code
free(li);
return 1;
}
上面的代码中free()
有什么问题。正确吗?
您忘记为终止空字符分配空间。
该行
res[cur]=(char *)malloc(strlen(str));
应该是
res[cur]=(char *)malloc(strlen(str) + 1);
还应检查返回值malloc()
NULL
。
main 中的自由不正确。它只释放分配给 li 指针的内存,而不释放分配给与其关联的指针数组的内存。
释放 li 指针后,分配给与其关联的指针数组的内存将变得无法访问,这是错误的。
释放所有内存的正确方法如下:
free(li[0]);
free(li[1]);
free(li[2]);
在此声明之后,应该有:
free(li);
希望会有所帮助!!
代码中存在多个问题:
- 为什么为 5 个指针分配空间而只使用 4 个指针?
- 为什么要为
str
分配 10 个字节,将字符串复制到其中,复制该字符串并为每次迭代释放 str? - 您不会在
"Maneger"
的副本中为空终止符分配空间。 - 您不会释放
li
中的字符串。 - 您不检查潜在的
malloc
故障。
这是更正后的版本:
#include <stdlib.h>
#include <string.h>
void free_test(char **a) {
if (a) {
for (int i = 0; a[i]; i++) {
free(a[i]);
}
free(a);
}
}
char **test(void) {
char **res = malloc(sizeof(*res) * 4);
if (res) {
int cur;
for (cur = 0; cur < 3; cur++) {
res[cur] = strdup("Maneger");
if (res[cur] == NULL) {
free_test(res);
return NULL;
}
}
res[cur] = NULL;
}
return res;
}
int main(int argc, char *argv[]) {
char **li = test();
if (li == NULL)
return 1;
//some code
free_test(li);
return 0;
}
strdup()
是一种更简单、更安全的字符串复制方法。它不是标准 C 的一部分,但在 Posix 和其他系统上受支持。 如果它在系统上不可用,可以通过以下方式重新定义:
char *strdup(const char *s) {
size_t len = strlen(s);
char *p = malloc(len + 1);
if (p != NULL) {
memcpy(p, s, len + 1);
}
return p;
}