[英]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.