0

簡単に言えば、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 */
    }
}

この関数ポインターの概要を読みましたが、問題を解決する方法をまだ判断できません。私が間違っていることの説明をいただければ幸いです。

4

1 に答える 1

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

また、安全のために、関数ポインターを使用して呼び出しを行う前に、関数ポインターが null でないことを確認するのが好きです

したがって、dl_delete では次のようになります:-

if(dl_destructor!=NULL) dl_destructor(node->object);
于 2013-02-13T03:10:35.967 に答える