Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将空指针传递给函数指针_C_Function Pointers_Void Pointers - Fatal编程技术网

C 将空指针传递给函数指针

C 将空指针传递给函数指针,c,function-pointers,void-pointers,C,Function Pointers,Void Pointers,简而言之,我试图使用一个void指针作为函数指针的参数,但是得到了编译器错误“void表达式的使用无效” 我有一个双链表(DLL),其节点结构如下: typedef struct DL_LIST { uint16 tag; /* Object ID tag */ struct DL_LIST *previous; struct DL_LIST *next; void *object; /* A point

简而言之,我试图使用一个void指针作为函数指针的参数,但是得到了编译器错误“void表达式的使用无效”

我有一个双链表(DLL),其节点结构如下:

typedef struct DL_LIST
{
    uint16 tag;                 /* Object ID tag */
    struct DL_LIST *previous;
    struct DL_LIST *next;
    void *object;               /* A pointer to this node's object */
    uint32 size;                /* The size of this node's object, in bytes */
} DL_LIST;
我还有以下功能,用于删除单个此类节点:

void dl_delete(DL_LIST *node, void (*dl_destructor)(void*)) {
    if (node != NULL) {
        dl_extract(node);       /* Removes the node from the list */

        if (node->object != NULL) {
            (*dl_destructor)(node->object);

            free(node->object);
        }

        free(node);
    }
}
其中,节点提取功能为:

DL_LIST *dl_extract(DL_LIST *node) {
    if (node != NULL) {
        if (node->previous != NULL) {
            node->previous->next = node->next;
        }

        if (node->next != NULL) {
            node->next->previous = node->previous;
        }

        node->previous = NULL;
        node->next = NULL;
    }

    return node;
}
这里的想法是能够为可能存储在节点中的每种类型的
对象
传递一个单独的析构函数。此析构函数将指向对象的指针作为参数,用于释放
对象的子对象使用的所有堆内存

当我试图从设计用于删除整个DLL的函数中调用
dl_delete()
时,会出现上述错误:

void dl_destroy(DL_LIST **list, void (*dl_destructor)(void*)) {
    DL_LIST *marker;
    DL_LIST *previous_node;

    if (*list != NULL) {
        previous_node = (*list)->previous;

        while (previous_node != NULL) {
            marker = previous_node->previous;
            dl_delete(previous_node, (*dl_destructor)(previous_node->object));
            previous_node = marker;
        }

        /* Code removed for brevity */
    }
}
我已经阅读了函数指针的介绍,但仍然无法确定如何解决这个问题。如果您能解释一下我做错了什么,我将不胜感激。

这一行

dl_delete(previous_node, (*dl_destructor)(previous_node->object));
需要
dl_delete(上一个节点,dl_析构函数)

同样在dl_中删除这一行
(*dl_析构函数)(节点->对象)

应该是
dl_析构函数(节点->对象)

另外,为了安全起见,我喜欢在尝试使用函数指针进行调用之前检查它们是否为null

因此,在dl_中删除如下内容:-

if(dl_destructor!=NULL) dl_destructor(node->object);
这条线

dl_delete(previous_node, (*dl_destructor)(previous_node->object));
需要
dl_delete(上一个节点,dl_析构函数)

同样在dl_中删除这一行
(*dl_析构函数)(节点->对象)

应该是
dl_析构函数(节点->对象)

另外,为了安全起见,我喜欢在尝试使用函数指针进行调用之前检查它们是否为null

因此,在dl_中删除如下内容:-

if(dl_destructor!=NULL) dl_destructor(node->object);

为了完整性,您可能希望在问题中包含
dl\u extract(node)
函数。@Floris感谢您的建议。为了完整性,您可能希望在问题中包含
dl\u extract(node)
函数。@Floris感谢您的建议。在您第一次推荐的更改中,Keith,为什么要从
dl\u析构函数中删除object参数?如果没有它,函数如何工作?因为您希望传递指向函数的指针。。。。。您似乎想做的是调用函数。一旦你声明了一个函数指针。它充当普通指针。当您想要调用它指向的函数时,您只需调用指针,就好像它是一个很难解释的函数一样,但您使用有趣的函数指针语法的唯一时间是在声明它时。(人们经常键入def it)在第一次建议的更改Keith中,为什么要从
dl_析构函数中删除object参数?如果没有它,函数如何工作?因为您希望传递指向函数的指针。。。。。您似乎想做的是调用函数。一旦你声明了一个函数指针。它充当普通指针。当您想要调用它指向的函数时,您只需调用指针,就好像它是一个很难解释的函数一样,但您使用有趣的函数指针语法的唯一时间是在声明它时。(人们经常输入def)