我有一个结构,比如
typedef struct {
void* data;
int index;
} Node;
我有一些像
这样的行 Node* node = (Node*)malloc(sizeof(Node));
enqueue(&list, node);
然后我有一个功能:
delete_node(Node* node) {
free(node->data);
free(node);
}
考虑free(node->data);
。如果data
是指向堆数据的指针,那很好,但如果它是引用则存在问题。我该如何处理? (标签已经很明显,但只是为了强调它:这不是一个C ++问题。)
答案 0 :(得分:3)
首先,C没有引用,所以让我们停止使用该特定术语。
我相信你问的是,你怎么知道一个指针是指向由malloc
(或其中一个表兄弟)分配的东西,还是一个分配有自动存储持续时间的对象。
答案是;你不能。提供分配node
的函数,并记录必须使用这些函数的文档。如果它们不是,并且客户端传入,例如,指向本地的指针,则行为未定义。所以,你有类似......
node *alloc_node(size_t size);
void free_node(node *node);
如果我将Node*
传递给未free_node
未分配的alloc_node
,则行为未定义,这是我的错。这是C中非常常见的习语。
想一想; free
有同样的问题,对吗?你当然可以这样做:
int main()
{
int i = 0;
free(&i);
return 0;
}
嗯,free
并不关心。即使它确实没有(理智)它可以做到检测这种情况。责任在你(我们)身上。如果您以不打算使用它的方式使用它,则行为是不确定的,并且您得到了您应得的。
答案 1 :(得分:0)
没有(便携式)方式判断指针是指向通过malloc
分配的内存还是指向static
或auto
变量。您需要设计代码,以便只为data
成员分配malloc
调用的结果。