为 2D 数组调用 free() 会导致 seg。过错

Posted

技术标签:

【中文标题】为 2D 数组调用 free() 会导致 seg。过错【英文标题】:Calling free() for 2D array results in seg. fault 【发布时间】:2012-02-04 20:27:11 【问题描述】:

我正在尝试学习 C,并且我已经到了这样的地步,我想尝试一些比将文本打印到控制台的小而简单的示例、以非常简单的方式使用指针等等更高级的东西。

问题是我的程序在我调用 free 时崩溃了,我确定是指针以某种方式困扰着我......

所以,我创建了一个这样的二维数组:

bool InitializeGrid(struct Grid *g, int rows, int columns)

    g->rows = rows;
    g->columns = columns;
    g->grid = malloc(g->rows * sizeof(int *));

    if(g->grid == NULL)
    
        printf("Could not allocate memory for grid rows.\n");
        return false;
    

    for (int i = 0; i < g->rows; i++)
    
        g->grid[i] = malloc(g->columns * sizeof(int));

        if(g->grid[i] == NULL)
        
            printf("Could not allocate memory for grid columns.\n");
            return false;
        
    

    / ... /

    return true;

Grid的结构如下:

struct Grid

    int rows;
    int columns;
    int **grid;
;

然后我在整个程序中成功使用了网格,一切都很好。当程序即将退出时,我需要/想要释放我分配的内存。我就是这样做的:

void CleanupGrid(struct Grid *g)

    for(int i = 0; i < g->rows; i++)
        free(g->grid[i]);

    free(g->grid);

但在第一次 free(g->grid[i]) 时,我收到了分段错误。

为什么这不起作用?我该如何解决这个问题?

编辑:

stdbool.h 已包含在程序中,供 bool/true/false 使用。

我真的很愚蠢地盯着 free() 语句看。当我将程序缩小到绝对最小值时,它与 free() 语句配合得很好。当我在某一时刻访问和写入网格时,free() 以分段错误迎接我。

接受 user1083265 的回答。

【问题讨论】:

您能否添加一个最小的main 函数来调用InitializeGridCleanupGrid 并导致段错误?此外,C 中没有 truefalse 这样的东西。您应该在其他地方将它们替换为 1 和 0 或 #define @Jan &lt;stdbool.h&gt;,自 1999 年起成为 C 的一部分。 【参考方案1】:

我编译了你的代码(只是 alloc/dealloc),它不会崩溃。

可能,当使用分配的网格时,您破坏了分配片段上方的一些内存。 Glibc 使用canary values 来检测这种损坏 - 因此在释放损坏的内存时会出现段错误。

【讨论】:

以上是关于为 2D 数组调用 free() 会导致 seg。过错的主要内容,如果未能解决你的问题,请参考以下文章

500,000 个已排序整数数组上的 C++ 快速排序算法中的 Seg 错误

将 2D 数组附加到 3D 数组,扩展第三维

调用 free() 或 delete 而不是 delete[] 有啥危险吗? [复制]

使用 scikit-learn 预测单个值会导致 ValueError

cudaMemcpy2D 导致段错误

使用 free() 释放内存导致崩溃