我有以下结构
typedef struct test {
int action;
void *data;
void (*function)(int, void*);
} test;
int execute_func(void(*function)(int a, void *d), int action, void *data)
{
struct test *todo;
todo = calloc (1,sizeof(struct test));
if (todo == NULL)
{
return -1;
}
todo->action = action;
todo->data = data;
todo->function = function;
todo->function(todo->action, todo->data);
return 0;
}
执行该功能后,我想通过以下方式释放已分配的结构:
if(todo != NULL)
{
if(todo->data != NULL)
{
free(todo->data);
}
if(todo->function != NULL)
{
free(todo->function); //Cause a crash
}
free(todo);
}
但是我遇到了崩溃。
答案 0 :(得分:2)
在运行时不分配函数。实际上你永远不必释放函数指针! 试图释放函数指针会调用未定义的行为。
您必须只释放您分配的内容。您的释放代码过于动态并释放了代码未分配的字段。对于所有你知道的数据,数据可能是指向全局或自动(即堆栈)存储中的对象的指针,因此它被设想为释放它。
答案 1 :(得分:2)
您只能释放已使用malloc
分配的内存。所以,你不能自由发挥功能。函数指针存储静态存储器中的地址。
if(todo != NULL)
{
if(todo->data != NULL)
{
free(todo->data);
}
free(todo);
}
此外,对data
的同一评论:您必须仅将释放,并且仅当data
指向的内存已使用malloc
动态分配。< / p>
从更通用的角度来看,如果你是它的拥有者,那么只有自由动态分配的内存。
要回答其中一条OP注释,当您对结构使用calloc
时,只为结构分配内存:int
和两个指针。您没有为函数分配内存,也没有为数据指向的内存分配内存。为了避免内存泄漏,你只需从你的结构中释放内存,即一个int
和两个指针(而不是指向内存,因为你不知道它们是怎么回事已分配)
答案 2 :(得分:2)
这很简单:您只能free()
使用malloc
/ calloc
分配的内容。如果您没有为某个项目致电malloc
/ calloc
,则不能free
它或程序崩溃。
良好的程序设计规定,与“execute_func”(可以使用更有意义的名称)一起,还应该有free
所在的相应清理功能。
如果检查指针是否为NULL,则必须1)确保所有指针都初始化为NULL,并且2)在为该指针调用free
之后将每个指针设置为NULL。
作为旁注,free
如果你向它传递一个空指针就有明确定义的行为:它将不执行任何操作。
答案 3 :(得分:2)
您无法释放函数指针。
只能释放malloc()
或类似函数返回的指针。
一个函数指针只是指向一个保存该函数的静态内存,你不需要释放它。只有动态分配的内存才能被释放。
更多争论点: