C 为什么free()会在我的代码中导致错误,而它';它在那里,但当它不在那里时,一切都运转良好?
我的程序在运行时获取任意数量的单词,并将它们存储在一个动态大小的单词数组中 目前,我的程序运行良好,但使用C 为什么free()会在我的代码中导致错误,而它';它在那里,但当它不在那里时,一切都运转良好?,c,memory-management,malloc,dynamic-memory-allocation,realloc,C,Memory Management,Malloc,Dynamic Memory Allocation,Realloc,我的程序在运行时获取任意数量的单词,并将它们存储在一个动态大小的单词数组中 目前,我的程序运行良好,但使用free()释放临时双指针temp的内存时除外。我不太清楚它为什么会这样做,因为我认为如果我不使用它会导致错误 int wordSize = 10, arrSize = 1, i = 0; char **stringArr, **temp; char *input; stringArr = malloc(arrSize * sizeof(char *)); puts("Acce
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()
的程序,所以我只是刚刚习惯了它们的工作方式。如果你知道一个更好的方法来完成我正在做的事情,请随意描述。免费(temp)代码>行导致错误(稍后),因为在前一行中,stringArr=temp代码>,则将存储在temp
指针中的地址分配给stringArr
指针中的地址。因此,当您释放由temp
指向的内存时,您也会释放由stringArr
指向的内存,因为它是相同的内存块。将指针的值从一个变量复制到另一个变量不会对内存进行(单独)复制
省略free(温度)代码>行是正确的,因为该内存稍后在free(stringArr)中被释放代码>调用。重新分配成功时,不能释放重新分配的阵列。如果您这样做,代码将修改这个已释放的块,它具有未定义的行为,并且当您稍后尝试重新分配或释放此块时,您将具有进一步的未定义行为
还应注意以下事项:
- 无需预先分配大小为
1
的stringArr
。只需将stringArr
初始化为0
并将arrSize
初始化为0
realloc()
可以接受空指针,其行为类似于malloc()
stringArr[i]=malloc(sizeof(input))
不正确:它将根据目标体系结构上指针的大小分配大小为4或8的char
数组,而不是应该分配的11
字节
- 如果
wordSize
是一个单词的最大长度,则应为空终止符再分配一个字节。%10s
中的10
必须与wordSize
的值匹配,这很麻烦,因为没有简单的方法将其作为变量传递给scanf()
- 您不检查
scanf()
的返回值,导致文件过早结束时出现未定义的行为
- 内存泄漏:
input
分配给每个迭代,但从未释放,释放stringArr
而不释放其元素指向的字符串会使它们无法访问
如果使用本地数组尝试使用scanf()
读取单词,并且仅在成功时分配字符串并重新分配数组,则效率会更高
以下是修改后的版本:
#包括
#包括
#包括
int main(){
int arrSize=0;
char**stringArr=NULL;
字符输入[11];
puts(“接受输入…”);
而(扫描频率(“%10s”,输入)==1&&strcmp(输入,“结束”)!=0){
字符**temp=realloc(stringArr,(arrSize+1)*sizeof(*stringArr));
如果(温度!=NULL){
stringArr=温度;
}否则{
puts(“无法分配更多内存”);
打破
}
stringArr[arrSize]=strdup(输入);
if(stringArr[arrSize]==NULL){
puts(“无法分配更多内存”);
打破
}
arrSize++;
}
puts(“数组内容:”);
对于(int i=0;i
尝试与valgrindAh一起运行,是的!我经常犯错误,忘记指针是这样工作的。非常感谢,阿德里安:)谢谢你的帮助,伙计。我感谢您提供的信息:)