【问题标题】:C - freeing struct containing a 2d arrayC - 释放包含二维数组的结构
【发布时间】:2015-10-15 13:41:41
【问题描述】:
#define LEVEL_MAX_WIDTH 25
#define LEVEL_MAX_HEIGHT 12

typedef struct Level 
{
    Cell cells[LEVEL_MAX_HEIGHT][LEVEL_MAX_WIDTH]; /* Cell is also a struct */
    int width;
    int height;
} Level; 

void level_free(Level* level)
{
    /* Free cells*/
    for (int i = 0; i < level->height; i++) {
        for (int j = 0; j < level->width; j++) {
            free(level->cells[i][j]);
        }
    }
    free(level);
}

当我调试我的level_Free(Level*) 方法时,我发现了一些奇怪的地方。

在第一次迭代 (i=0 and j=0) 期间,在调用方法 free(level-&gt;cells[i][j] 之后:level-&gt;[i] 中的所有其他单元格都被释放。

释放一个 Cell 元素会导致释放该元素所在的整个数组。

谁能解释为什么会这样?

编辑: 这就是我“创建”我的细胞的方式:

            Cell* cell = malloc(sizeof(Cell)); 
            cell->row = r;
            cell->col = c;
            cell->type=level_symbol_to_cell_type(symbol);
            cell->owner=level_symbol_to_owner(symbol);
            /* place cell */
            level->cells[r][c] = *cell;

typedef struct Cell 
{
    int row;
    int col;
    CellType type; /* enum */
    Owner owner; /* enum also */
} Cell;

【问题讨论】:

  • 这里没有什么可以释放的,除非Cell 被定义为指向结构的指针。如果Cell 只是一个结构,那么您的Level 结构会保存所有数据。你可能也没有malloc 任何东西,是吗?你怎么知道“其他细胞被释放了”?
  • 我什至不明白你是如何观察到的/为什么你认为元素被释放了。
  • 您必须提供更多上下文,因为没有人可以仅通过查看该函数来回答问题。
  • 我认为这需要一堆额外的代码上下文才能解决。它部分取决于您的 cell 结构是如何定义的。
  • 在循环之前,我保存了所有单元格的地址。在第一次 free() 调用之后,我检查了所有这些地址的值,发现它们失去了价值。

标签: c struct free


【解决方案1】:

如果每个 Cell 是一个结构而不是指向动态分配内存的指针,则不应单独释放数组的成员。

您需要动态释放已动态分配的内存。如果你有malloc 的关卡,你需要free 它。

但数组及其成员的内存位于为关卡分配的内存块中。您在评论中注意到 Cell 是一个结构。因此,每个 Cell 的内存都包含在为 Level 分配的内存块中,并通过释放 Level 来处理。

void level_free(Level* level)
{
    free(level);
}

您的编辑显示 Cell 本身没有指向动态分配的内存。 如果是这样,你也必须释放它。

void level_free(Level* level)
{
    /* Free cells*/
    for (int i = 0; i < level->height; i++) {
        for (int j = 0; j < level->width; j++) {
            cell_free( & level->cells[i][j]);
        }
    }
    free(level);
}

void cell_free( Cell * level) {
    ...
}

【讨论】:

  • 那么 free(level) 就足以释放级别指针及其所有内容了吗?
  • “不需要单独免费”令人困惑;听起来好像“如果你勤奋,你可以释放它”。如果您释放了不需要释放的东西,则会出现未定义的行为,这可能会导致“所有其他元素都被释放”。
  • @Domien - 这取决于内容是否指向(和拥有)任何动态分配的内存。如果没有,free(level) 就足够了。但如果有,您还必须释放内容中指向的动态分配的内存。
  • 你真的应该先要求澄清。这是一个混乱的问题,必然会吸引混乱的答案。强烈反对投票。
  • @Domien - 如果您发布 Cell 的结构定义,我们可以更具体。
【解决方案2】:

你应该free 只指向动态分配的内存,否则行为是不确定的。 如果您为Level 动态分配内存,那么仅释放返回的指针也会释放数组。

【讨论】:

    猜你喜欢
    • 2018-05-09
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    相关资源
    最近更新 更多