问题描述
我的程序在运行时接受任意数量的单词,并将它们存储在动态大小的单词数组中。
当前,我的程序运行良好,除了使用free()
释放临时双指针temp
的内存外。我不太确定为什么要这样做,因为我认为如果不使用它会导致错误。
int wordSize = 10,arrSize = 1,i = 0;
char **stringArr,**temp;
char *input;
stringArr = malloc(arrSize * sizeof(char *));
puts("Accepting input...");
for (;;) {
if (i >= arrSize) {
arrSize += 1;
temp = realloc(stringArr,arrSize * sizeof(char *));
if (temp != NULL) {
stringArr = temp;
free(temp); // This is the line that is giving me issues; removing it works
} else {
puts("Could not allocate more memory");
return 0;
}
}
stringArr[i] = malloc(sizeof(input));
input = malloc(wordSize * sizeof(char));
scanf("%10s",input);
if (strcmp(input,"END")) {
strcpy(stringArr[i],input);
i++;
} else
break;
}
free(stringArr);
在程序的底部,我使用free()
没有任何问题。在这里,它如何工作正常,但在程序的较早版本中没有。
我觉得我缺少关于free()
的工作方式的信息。
注意:这是我第一个实现malloc()
和realloc()
的程序,因此我只是习惯于它们的工作方式。如果您知道实现我正在执行的操作的更好方法,请随时描述。
解决方法
free(temp);
行引起错误(以后),因为在上一行stringArr = temp;
中,您正在分配存储在{{ 1}}指向temp
指针中的指针。因此,当您释放stringArr
指向的内存时,您也释放了temp
指向的内存,因为它是相同内存块。将指针的值从一个变量复制到另一个不会进行内存的(单独)副本。
省略stringArr
行是正确的,因为稍后会在free(temp);
调用中释放该内存。
重新分配成功后,您不得释放重新分配的阵列。如果这样做,代码将修改此已释放的块,该块具有未定义的行为,并且在以后尝试重新分配或释放此块时,您将具有进一步的未定义的行为。
还请注意以下几点:
-
无需预先分配大小为
stringArr
的{{1}}。只需将1
初始化为stringArr
,并将0
初始化为arrSize
。0
可以使用空指针,其行为类似于realloc()
。 -
malloc()
是错误的:它将根据目标体系结构上的指针大小而不是stringArr[i] = malloc(sizeof(input));
个字节来分配大小为4或8的char
数组 -
如果
11
是一个单词的最大长度,则应为空终止符再分配一个字节。wordSize
中的10
必须与%10s
的值匹配,这很麻烦,因为没有简单的方法将其作为变量传递给wordSize
。 -
您不检查
scanf()
的返回值,如果文件过早结束,则会导致不确定的行为。 -
您有内存泄漏:
scanf()
为每次迭代分配,但从未释放,释放input
而不释放其元素指向的字符串会使它们不可访问。
使用本地数组尝试使用stringArr
读取单词,然后仅分配字符串,如果成功,则重新分配数组会更有效。
这是修改后的版本:
scanf()