当*指向函数时崩溃

时间:2022-08-19 16:56:18

I have the following struct

我有以下结构

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

After executing the function, i want to free the allocated structure usinf the following:

执行该函数后,我想通过以下方式释放分配的结构:

if(todo != NULL)
{
    if(todo->data != NULL)
    {
        free(todo->data);
    }
    if(todo->function != NULL)
    {
        free(todo->function); //Cause a crash
    }
    free(todo);
}

but i get a crash.

但是我遇到了崩溃。

4 个解决方案

#1


2  

You only can free memory that have been allocated with malloc. So, you can't free function. A function pointer stores address from static memory.

您只能释放已使用malloc分配的内存。所以,你不能*功能。函数指针存储来自静态存储器的地址。

if(todo != NULL)
{
    if(todo->data != NULL)
    {
        free(todo->data);
    }
    free(todo);
}

Also, same remark for data: you have to free it only and only if memory pointed by data have been dynamically allocated with malloc.

此外,对数据也是如此:只有在数据指向的内存已经使用malloc动态分配时才必须释放它。

And to a more generic point of view, only free dynamically allocated memory if you are owner of it.

从更通用的角度来看,如果你是它的拥有者,那么只有*动态分配的内存。

To answer of one of OP comments, when you use calloc to your structure, you allocate memory for structure only: an int and two pointer. You don't have allocated memory for function nor for memory pointed by data. To avoid memory leak, you just have to free memory from your structure, ie an int and two pointer (and not for pointed memory, because you don't know how they had been allocated)

要回答OP注释之一,当您对结构使用calloc时,只为结构分配内存:一个int和两个指针。您没有为函数分配内存,也没有为数据指向的内存分配内存。为了避免内存泄漏,你只需从结构中释放内存,即一个int和两个指针(而不是指向内存,因为你不知道它们是如何被分配的)

#2


2  

Functions are not allocated at runtime. In fact you never must free function pointers! Trying to free a function pointer invokes undefined behaviour.

函数不在运行时分配。事实上,你永远不必释放函数指针!尝试释放函数指针会调用未定义的行为。

You must free only what you allocated. Your freeing code is overmotivated and frees fields which were not allocated by your code. For all you know data may be a pointer to an object in global or automatic (i.e. stack) storage so it's ill conceived to free that.

您必须只释放您分配的内容。您的释放代码过度动态并释放未由您的代码分配的字段。对于你所知道的所有数据,数据可能是指向全局或自动(即堆栈)存储中的对象的指针,因此可以设想释放它。

#3


2  

It's really simple: you can only free() what you have previously allocated with malloc/calloc. If you didn't call malloc/calloc for a certain item, you can't free it or the program will crash.

这很简单:你只能释放()以前用malloc / calloc分配的东西。如果您没有为某个项目调用malloc / calloc,则无法释放它,否则程序将崩溃。

Good program design dictates that together with your "execute_func" (which could do with a more meaningful name) there should also be a corresponding clean-up function where free is located.

良好的程序设计要求与“execute_func”(可以使用更有意义的名称)一起使用,还应该有一个相应的清理功能,其中有free。

And if you check a pointer against NULL, you must 1) make sure that all pointers are initialized to NULL, and 2) set every pointer to NULL after calling free for that pointer.

如果检查指针是否为NULL,则必须1)确保所有指针都初始化为NULL,并且2)在为该指针调用free之后将每个指针设置为NULL。

As a side note, free has well-defined behavior if you pass a null pointer to it: it will then do nothing.

作为旁注,如果您向其传递一个空指针,则free具有明确定义的行为:它将不执行任何操作。

#4


2  

You can't free a function pointer.

你不能释放一个函数指针。

Only pointers returned by malloc() or similar functions can or have to be freed.

只能释放malloc()或类似函数返回的指针。

A function pointer simply points to a piece of static memory holding the function, you do not need to free it. Only dynamically allocated memory has to be freed.

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

More points of contention:

更多争论点:

  • Freeing a pointer doesn't set the variable holding the pointer to NULL, you have to do that yourself if you want to use it in a conditional check
  • 释放指针不会将保持指针的变量设置为NULL,如果要在条件检查中使用它,则必须自己执行此操作
  • Freeing NULL will not crash your program, but do nothing instead ("If ptr is a null pointer, the function does nothing.")
  • 释放NULL不会使程序崩溃,而是不执行任何操作(“如果ptr是空指针,则该函数不执行任何操作。”)

#1


2  

You only can free memory that have been allocated with malloc. So, you can't free function. A function pointer stores address from static memory.

您只能释放已使用malloc分配的内存。所以,你不能*功能。函数指针存储来自静态存储器的地址。

if(todo != NULL)
{
    if(todo->data != NULL)
    {
        free(todo->data);
    }
    free(todo);
}

Also, same remark for data: you have to free it only and only if memory pointed by data have been dynamically allocated with malloc.

此外,对数据也是如此:只有在数据指向的内存已经使用malloc动态分配时才必须释放它。

And to a more generic point of view, only free dynamically allocated memory if you are owner of it.

从更通用的角度来看,如果你是它的拥有者,那么只有*动态分配的内存。

To answer of one of OP comments, when you use calloc to your structure, you allocate memory for structure only: an int and two pointer. You don't have allocated memory for function nor for memory pointed by data. To avoid memory leak, you just have to free memory from your structure, ie an int and two pointer (and not for pointed memory, because you don't know how they had been allocated)

要回答OP注释之一,当您对结构使用calloc时,只为结构分配内存:一个int和两个指针。您没有为函数分配内存,也没有为数据指向的内存分配内存。为了避免内存泄漏,你只需从结构中释放内存,即一个int和两个指针(而不是指向内存,因为你不知道它们是如何被分配的)

#2


2  

Functions are not allocated at runtime. In fact you never must free function pointers! Trying to free a function pointer invokes undefined behaviour.

函数不在运行时分配。事实上,你永远不必释放函数指针!尝试释放函数指针会调用未定义的行为。

You must free only what you allocated. Your freeing code is overmotivated and frees fields which were not allocated by your code. For all you know data may be a pointer to an object in global or automatic (i.e. stack) storage so it's ill conceived to free that.

您必须只释放您分配的内容。您的释放代码过度动态并释放未由您的代码分配的字段。对于你所知道的所有数据,数据可能是指向全局或自动(即堆栈)存储中的对象的指针,因此可以设想释放它。

#3


2  

It's really simple: you can only free() what you have previously allocated with malloc/calloc. If you didn't call malloc/calloc for a certain item, you can't free it or the program will crash.

这很简单:你只能释放()以前用malloc / calloc分配的东西。如果您没有为某个项目调用malloc / calloc,则无法释放它,否则程序将崩溃。

Good program design dictates that together with your "execute_func" (which could do with a more meaningful name) there should also be a corresponding clean-up function where free is located.

良好的程序设计要求与“execute_func”(可以使用更有意义的名称)一起使用,还应该有一个相应的清理功能,其中有free。

And if you check a pointer against NULL, you must 1) make sure that all pointers are initialized to NULL, and 2) set every pointer to NULL after calling free for that pointer.

如果检查指针是否为NULL,则必须1)确保所有指针都初始化为NULL,并且2)在为该指针调用free之后将每个指针设置为NULL。

As a side note, free has well-defined behavior if you pass a null pointer to it: it will then do nothing.

作为旁注,如果您向其传递一个空指针,则free具有明确定义的行为:它将不执行任何操作。

#4


2  

You can't free a function pointer.

你不能释放一个函数指针。

Only pointers returned by malloc() or similar functions can or have to be freed.

只能释放malloc()或类似函数返回的指针。

A function pointer simply points to a piece of static memory holding the function, you do not need to free it. Only dynamically allocated memory has to be freed.

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

More points of contention:

更多争论点:

  • Freeing a pointer doesn't set the variable holding the pointer to NULL, you have to do that yourself if you want to use it in a conditional check
  • 释放指针不会将保持指针的变量设置为NULL,如果要在条件检查中使用它,则必须自己执行此操作
  • Freeing NULL will not crash your program, but do nothing instead ("If ptr is a null pointer, the function does nothing.")
  • 释放NULL不会使程序崩溃,而是不执行任何操作(“如果ptr是空指针,则该函数不执行任何操作。”)