【发布时间】:2019-12-05 21:13:56
【问题描述】:
我正在分配一个动态分配的指针数组,并尝试在程序结束时释放它们。问题是我总是在 valgrind 上收到“invalid free()”错误,尽管我真的找不到问题所在。 例如:我使用 malloc 为 argv[0] 和 argv1 分配内存,然后尝试在 for 循环中释放它们。 我使用以下方法分配指针数组:
char ucom[10], bin[15] = "/bin/";
char* str = (char *) malloc(MAX_LINE_LENGTH*sizeof(char));
char** argv = (char **) malloc(sizeof(char*)); //ALLOCATING MEMORY FOR ARGV
int status, i = 0;
printf("Shell2$**");
strcpy(bin, "/bin/");
fgets(str, MAX_LINE_LENGTH, stdin);
char *token;
token = strsep(&str, " ");
while(token != NULL && i < 4){
if(token[strlen(token)-1] == '\n')
token[strlen(token)-1] = '\0';
argv[i] = (char *) malloc(MAX_ARGUMENT_LENGTH*sizeof(char)); //ALLOCATING MEMORY FOR POINTERS INSIDE ARGV, running two times in my example
printf("\n\nI:%d\n\n",i);
if(argv[i] == NULL) printf("Memory Allocation Problem");
argv[i] = token;
token = strsep(&str, " ");
i++;
argv = (char **)realloc(argv, (i+2)*sizeof(char*));
}
然后我尝试释放它们:
wait(&status);
for(int f = 0; f < i; f++){
if(argv[f] != NULL)
free(argv[f]); //Free runs two times as the number of time malloc has been called, but fails at the second free.
}
free(str);
free(argv);
尽管 malloc 在我的示例中运行了 2 次,为 argv[0] 和 argv1 分配了内存,但当最后的 for 循环尝试释放 argv1 时,它失败并且 valgrind 说这是free 无效,但它成功释放了 argv[0]。
提前谢谢大家!
valgrind 的输出: LINK
【问题讨论】:
-
请提供minimal verifiable example。尝试对不完整的代码进行评论是没有效率的,因为问题甚至可能不在您展示的部分。例如,分配代码是否在函数内部?一个常见的错误是将内存分配给本地范围变量并在调用者中释放。但是我们无法从您不完整的代码中判断是否是这种情况。因此,为什么我们总是要求一个最小的可验证示例。
-
argv[i] = token;-- 哎呀,你刚刚破坏了你之前做了两行的内存分配。也许你的意思是strcpy(argv[i], token);? -
您的
argv数组以一个元素开始,并且每个循环扩展一个指针,因此它总是比参数多一个(这是合理的),但最终指针不是无效。在while循环之后推荐argv[i] = NULL;。 -
能否请您编辑并减少不必要的缩进?它将提高可读性,特别是对于那些通过移动设备阅读的人(比如我)。
-
您需要将 Valgrind 的输出 作为文本 包含在问题中。