[英]Linked list in C – methods
假設我們有雙重鏈接的節點列表
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int value;
struct Node* next;
struct Node* prev;
} Node;
typedef struct LinkedList {
Node *first;
Node *last;
} LinkedList;
void initList(LinkedList* l) {
l->first = NULL;
l->last = NULL;
}
我必須編寫代碼方法,該方法將具有給定值的新節點插入列表的末尾,並返回指向該新節點的指針。 我的嘗試如下:
Node *insert(LinkedList *list, int value) {
Node node;
node.value = value;
node.prev = list->last;
node.next = NULL;
if (list->last != NULL){
(list->last)->next = &node;
}else{
list->first = &node;
list->last = &node;
}
return &node;
}
看來,在空列表中插入是可行的,但對於非空列表則無效。
(有一些實現測試,可以告訴我插入是否成功。我可以發布它們的代碼,但是並不重要)。
那么,請問錯誤在哪里?
日志中有一個警告(第51行是帶有“ return&node”的警告)
C:\...\main.c|51|warning: function returns address of local variable [-Wreturn-local-addr]|
那是個嚴重的問題嗎? 以及如何將其刪除?
感謝您的回答,但我認為非空列表仍然存在問題,因為根據測試,此操作失敗:
void test_insert_nonempty(){
printf("Test 2: ");
LinkedList l;
initList(&l);
Node n;
n.value = 1;
n.next = NULL;
l.first = &n;
l.last = &n;
insert(&l, 2);
if (l.last == NULL) {
printf("FAIL\n");
return;
}
if ((l.last->value == 2) && (l.last->prev != NULL)) {
printf("OK\n");
free(l.last);
}else{
printf("FAIL\n");
}
}
Node node;
是函數insert
的局部變量。 一旦您的函數終止並且不再定義,它就會被“銷毀”。 將指針返回到函數的局部變量是未定義的行為。 您必須分配動態內存。 動態分配內存將保留,直到您free
它:
Node *insert(LinkedList *list, int value) {
Node *node = malloc( sizeof( Node ) ); // allocate dynamic memory for one node
if ( node == NULL )
return NULL; // faild to allocate dynamic memory
node->value = value;
node->prev = list->last;
node->next = NULL;
if ( list->first == NULL )
list->first = node; // new node is haed of list if list is empty
else // if ( list->last != NULL ) // if list->first != NULL then list->last != NULL
list->last->next = node; // successor of last node is new node
list->last = node; // tail of list is new node
return node;
}
請注意,為避免內存泄漏,銷毀列表時必須free
列表的每個節點。
您要返回的非靜態局部變量的地址在從函數返回時將消失,從函數返回后取消引用該地址將調用未定義的行為 。
您必須分配一些緩沖區並返回其地址。
Node *insert(LinkedList *list, int value) {
Node *node = malloc(sizeof(Node));
if (node == NULL) return NULL;
node->value = value;
node->prev = list->last;
node->next = NULL;
if (list->last != NULL){
(list->last)->next = node;
}else{
list->first = node;
list->last = node;
}
return node;
}
您必須動態分配新節點。
否則函數中的變量node
Node *insert(LinkedList *list, int value) {
Node node;
//...
是該函數的局部變量,退出該函數后將不活動。 結果,用於訪問該變量的任何指針都將無效。
該功能可以看起來像
Node * insert( LinkedList *list, int value )
{
Node *node = malloc( sizeof( Node ) );
if ( node != NULL )
{
node->value = value;
node->prev = list->last;
node->next = NULL;
if ( list->last != NULL )
{
list->last->next = node;
}
else
{
list->first = node;
}
list->last = node;
}
return node;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.