假设我们有双向链表的节点
#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 节点;
是函数 insert
中的局部变量。一旦您的函数终止并且不再定义,它就会被“销毁”。返回指向函数局部变量的指针是未定义的行为。您必须分配动态内存。动态分配的内存会被保留,直到您释放
它为止:
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;
}
请注意,为了避免内存泄漏,当您销毁列表时,您必须释放
列表中的每个节点。
关于c - C 中的链表 – 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35680755/