Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么free()会在我的代码中导致错误,而它';它在那里,但当它不在那里时,一切都运转良好?_C_Memory Management_Malloc_Dynamic Memory Allocation_Realloc - Fatal编程技术网

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一起运行,是的!我经常犯错误,忘记指针是这样工作的。非常感谢,阿德里安:)谢谢你的帮助,伙计。我感谢您提供的信息:)