2013-02-13 205 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