2013-02-13 165 views
0

简而言之,我尝试使用void指针作为函数指针的参数,但得到编译器错误“无效使用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; 
} 

这里的想法是能够通过一个单独的可以存储在节点中的每种类型的object的析构函数。此析构函数将一个指向该对象的指针作为参数,并用于释放由object的子项使用的任何堆内存。

,当我尝试打电话dl_delete()从设计到删除整个DLL中的函数时,发生上述错误:

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 */ 
    } 
} 

我已阅读this介绍函数指针,但我仍然无法确定如何补救问题。我非常感谢解释我做错了什么。

+0

对于您可能要包括你的'dl_extract(节点)的问题'功能完整性。 – Floris 2013-02-13 03:13:59

+0

@弗洛里感谢您的建议。 – RBE 2013-02-13 03:18:42

回答

3

此行

dl_delete(previous_node, (*dl_destructor)(previous_node->object)); 

需求是dl_delete(previous_node, dl_destructor);

也dl_delete此行(*dl_destructor)(node->object);

应该dl_destructor(node->object);

还,只是为了安全,我想检查我的函数指针在尝试使用它们拨打电话之前不为空

所以dl_delete是这样的: -

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

在你第一次推荐的改变Keith中,为什么你从'dl_destructor'函数中删除了对象参数?没有它,该功能如何工作? – RBE 2013-02-13 03:24:18

+0

因为你想传递一个函数的指针.....你看起来试图做的是调用函数。一旦你声明了一个函数指针。它充当一个正常的指针。当你想调用它指向的函数时,你只需要调用指针就好像它的一个函数 – 2013-02-13 03:30:01

+0

啊 - 非常感谢你的解释。 – RBE 2013-02-13 03:31:56