【问题标题】:Debugging invalid free()调试无效的free()
【发布时间】:2014-09-24 03:34:22
【问题描述】:

我正在编写一个程序,我必须在其中管理一个字符串数组。在整个程序中,字符串被系统地删除/修改,直到只剩下一个字符串。

当不再需要字符串时,我会使用此函数将其删除:

void remove_element(char **array, int index, int array_length)
{
    int i;
    for(i = index; i < array_length - 1; i++){
        array[i] = array[i + 1];
    }
    free(array[array_length]);
}

一旦我完成了数组,我使用这个函数来确保所有的字符串都是空闲的:

void free_fragments(char **frags){
    int i = 0;
    while((frags[i] != NULL) && sizeof(frags[i] != 0)){
        free(frags[i]);
        i++;
     }
    free(frags);
}

然而,当我这样做时,valgrind 给我一个“无效的 free()/delete/delete[]/realloc()”错误,特别是抱怨 free_fragments 中的“free(frags[i])”行。

我知道 free_fragments 似乎有点多余,仅仅是因为理论上我可以在每个元素上调用 remove_element 直到剩下一个,然后再调用 remove_element ,但是当我尝试这样做时,我仍然得到一个 Invalid free()错误,但这次抱怨 remove_element。如果我在处理完数组后不调用 free_fragments,就会出现内存泄漏。

我对指针的理解还很初级,所以请帮我调试一下,提高我的理解!

【问题讨论】:

  • 我可以在您的代码中看到一些潜在的缺陷,但是如果没有看到您的代码的其余部分,特别是对 remove_elementfree_fragments 的调用,很难确定问题出在哪里。

标签: c pointers memory memory-management


【解决方案1】:

问题在于,当您执行free(array[array_length]); 时,您并没有将其设为 NULL,因此在 free_fragments 中您仍然认为它是一个有效指针。 想一想,你似乎释放了,错误的条目,也是......这应该工作:

void remove_element(char **array, int index, int array_length)
{
    int i;
    free(array[index]);
    for(i = index; i < array_length - 1; i++){
        array[i] = array[i + 1];
    }
    array[array_length-1] = NULL;
}

【讨论】:

    【解决方案2】:

    假设索引是指您要释放的二维数组中的字符串索引,我相信您的程序中存在内存泄漏。第一次迭代中要释放的字符串的内存地址不会丢失吗:array[index] = array[index + 1]。

    此外,您在最后一条语句中超出了数组的边界并完全释放了其他东西。基本上存在内存泄漏,您应该在使用@LaszloLadanyi 解决方案中定义的相邻字符串覆盖其地址之前释放该字符串。

       void remove_element(char **array, int index, int array_length)
       {
            int i;
            for(i = index; i < array_length - 1; i++){
                array[i] = array[i + 1];
            }
            /* Array indexes in C are in the range [0 - length-1]. Here 
               you are going outside array boundaries.
            */
            free(array[array_length]);
       }
    

    【讨论】:

      【解决方案3】:

      我认为您需要将代码修改为

      void remove_element(char **array, int index, int array_length)
      {
        int i;
        for(i = index; i < array_length - 1; i++){
            array[i] = array[i + 1];    //I don't understand what's purpose here
        }
        free_fragments(array);   //array[array_length] is a invalid pointer, out of range
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-21
        • 1970-01-01
        • 1970-01-01
        • 2013-06-27
        • 1970-01-01
        • 2016-07-21
        • 1970-01-01
        • 2015-03-31
        相关资源
        最近更新 更多