C - Struct构造函数和解构函数

时间:2016-08-01 16:57:04

标签: c pointers

如果我有一个结构:

struct Cell
{
    unsigned int *x, *y;
    char flag;
};

以下构造函数和解构器是否足以安全地分配和取消分配内存?

// Constructor function.
struct Cell *Cell_new()
{
    struct Cell *born = malloc(sizeof(struct Cell));
    if (born == NULL)
        return NULL;
    born->x = NULL;
    born->y = NULL;
    born->flag = false;
    return born;
}

// Deconstructor function.
// When called, use Cell_destroy(&cell);
char Cell_destroy(struct Cell **cell)
{
    free(cell);
    cell = NULL;
}

这是对的吗?

我不明白的一件事是,如果我这样做:

struct Cell *myCell = Cell_new();
Cell_destroy(&myCell);

当我正在调用destroy时,它期望一个地址指向一个指针(一个指向指针的指针),但我还是为一个结构提供了一个地址。

我的意思是

我的功能期望:

Pointer -> Pointer -> Tangible Object

我给予的是什么:

Pointer -> Tangible Object

这是有缺陷的逻辑吗?我已经查了一段时间了,所以可以说我可能会让自己感到困惑。

4 个答案:

答案 0 :(得分:5)

将类型struct Cell **的参数传递给析构函数是正确的,因为此函数将更改指针的值。

因此,如果要释放对象并将指针设置为NULL,则可以编写:

void Cell_destroy(struct Cell **cell)
{
    free(*cell);
    *cell = NULL;
}

请注意cell如何被取消引用。

答案 1 :(得分:1)

我会考虑结构中xy指针指向的内存。如果这些指针非空,那么代码的哪一部分负责(“拥有”)该内存?一个典型的做法是在Cell_destroy中检查null,如果x或y为非null,则在它们上面调用free,如果是你的Cell ADT的其他部分的情况(抽象数据类型)通过malloc动态分配该内存。可以肯定的是,free(cell)只释放结构本身使用的内存,而不释放xy指向的任何内存。

关于Cell_destroy获取指向指针的指针,因此可以将传入的指针设置为null,这是析构函数工作的一种非典型方式...... {{1}本身的工作更典型 - 将传入的指针归零通常是free调用者留下的工作。

答案 2 :(得分:1)

代码需要释放它分配的相同指针。释放取消引用的值。

代码也缺少返回值。建议只使用void函数。

代码还应该释放字段的指针xy

代码应该容忍使用相同指针和空指针的重复调用。添加if (*cell)

void Cell_destroy(struct Cell **cell) {
  if (*cell) {
    free((*cell)->x);
    free((*cell)->y);
    free(*cell);
    *cell = NULL;
  }
}

答案 3 :(得分:0)

不,这不正确。

destroy函数不应该返回char。它应该有返回类型void。

此外,该函数应该使用指针而不是双指针,并且不应将单元格设置为null。在调用destroy时不要接受myCell的地址。