假设我们有双重链接的节点列表
#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&amp; 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");
}
}
答案 0 :(得分:2)
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
列表中的每个节点。
答案 1 :(得分:1)
您返回的非静态局部变量的地址在从函数返回时将消失,并且在从函数返回后取消引用该地址会调用未定义的行为。
你必须分配一些缓冲区并返回它的地址。
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;
}
答案 2 :(得分:1)
您必须动态分配新节点。
您的函数中的变量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;
}