簡體   English   中英

使鏈表更加通用

[英]Making linked list more generic

有人可以幫助我使用鏈接列表來理解空指針。

我有:

struct listNode
{
    int nodeValue;
    struct listNode * next;
};

typedef struct listNode listNode;

僅適用於int。 如果將int nodeValue更改為void * nodeValue,如何使用void指針將值發送到鏈接列表中?

例如,我有一個添加到前台的功能:

void addFront(listNode *L, int number);

它需要一個listNode和一個數字。

如果它是一個void *指針,我可以將簽名更改為:

void addFront(listNode *L, void* value);

在使用整數的主要函數中,我有類似以下內容:

int main(void)
{   
    listNode *list;
    list = createList();

    for (int x = 0;x < 8;x++)
    {
        addFront(list,x);

    }

    return(0);
}

其中createList定義為:

listNode *createList()
{
    listNode *anyNode;
    anyNode = malloc(sizeof(listNode));
    anyNode->next = NULL;
    return anyNode;
}

listNode *initNode(int number)
{
    listNode *newNode;
    newNode = malloc(sizeof(listNode));
    newNode->nodeValue = number;
    newNode->next = NULL;
    return(newNode);
}

為了使列表更通用,我如何使用void *而不是聲明整數來傳遞整數。

不幸的是,這種通用行為是以大開銷為代價的:為了將int保存在列表中,您需要通過動態分配int來擴展其范圍:

listNode *initNode(int number)
{
    listNode *newNode;
    newNode = malloc(sizeof(listNode));
    newNode->nodeValue = malloc(sizeof(int));
    *(newNode->nodeValue) = number;
    newNode->next = NULL;
    return(newNode);
}

因為malloc(sizeof(int));這會多次增加內存需求malloc(sizeof(int)); 通常分配至少一個16字節的塊。

存儲整數或指針的一種方法是使nodeValue成為聯合類型。 請注意,為避免未定義的行為,您的調用代碼必須保持一致(即,如果將int添加到鏈表中,則以后不應嘗試將它們作為指針訪問,反之亦然)。

union intOrPointer
{
    int intValue;
    void * pointerValue;
};

struct listNode
{
    union intOrPointer nodeValue;
    struct listNode * next;
};

typedef struct listNode listNode;

listNode *initNode(int number)
{
    listNode *newNode;
    newNode = malloc(sizeof(listNode));
    newNode->nodeValue.intValue = number;
    newNode->next = NULL;
    return(newNode);
}

另一種解決方案是在listNode聲明中使用0-size數組。 例如:

#include <stdlib.h>
#include <string.h>

struct listNode
{
  struct listNode *next;
  int nodeValue[0];
};

struct listNode *addFront(struct listNode **head, void *data, size_t size)
{
  struct listNode *new_node = calloc(sizeof(struct listNode) + size, 1);
  if(!new_node)
    return NULL;
  new_node->next = *head;
  *head = new_node->next;
  memcpy(new_node->nodeValue, data, size);
}

void addInt2Front(struct listNode **head, int value)
{
  addFront(head, &value, sizeof(value));
}

int main(void)
{
  struct listNode *head = NULL;
  addInt2Front(&head, 5);
}

它減少了兩次分配的開銷,因為nodeValue的內存通過一次calloc()調用與listNode塊一起分配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM