当自由指向函数时崩溃

时间:2016-06-13 09:14:51

标签: c

我有以下结构

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);
}

但是我遇到了崩溃。

4 个答案:

答案 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()或类似函数返回的指针。

一个函数指针只是指向一个保存该函数的静态内存,你不需要释放它。只有动态分配的内存才能被释放。

更多争论点: