我在C中有一个链表。我想根据"库存水平"动态填充它。出于测试目的,我创建了一个小程序。这里的库存水平只是硬编码为1,但这足以证明。
在这段代码中,链表中的第一个节点是特殊的,所以我自己创建它,它总是保持不变。其余节点(其数量与"库存级别"匹配)是动态创建的。
我知道这个问题与范围有关,但我真的不确定是怎么回事。
如果我将"库存水平"设置为0,则一切正常。输出如下:
inside function: (5, 10)
outside function: (5, 10)
如果我将"库存水平"增加到1,输出看起来像这样:
inside function: (5, 10) ; Correct
inside function: (2, 3) ; Correct
outside function: (5, 10) ; Still Correct
outside function: (24, 48) ; What..?
outside function: (0, 1)
outside function: (1848777136, 32767)
我尝试malloc
链接列表的头,但我得到了类似的结果。我还尝试过malloc
——每个结构的.next
部分,同样得到了类似的结果。我已经尝试解决这个问题有一段时间了,最后只做了一个内联for循环来处理这个问题,但我真的希望它在一个单独的函数中(因为我不得不在几个地方重复特定的代码)。
谢谢你的帮助。
作为参考,这里是我正在使用的代码:
#include <stdlib.h>
struct Item {
int x;
int y;
struct Item *next;
};
void create(struct Item *start, int stock) {
*start = (struct Item){ .x = 5, .y = 10, .next = NULL };
int i;
struct Item *previous = start;
for (i = 1; i <= stock; i++ ) {
previous->next = &(struct Item){ .x = (i*2), .y = (i*3), .next = NULL };
previous = previous->next;
}
struct Item *node = start;
while (node != NULL) {
printf(" inside function: (%d, %d)n", node->x, node->y);
node = node->next;
}
}
int main() {
struct Item head;
int stock = 1;
create(&head, stock);
struct Item *node = &head;
while (node != NULL) {
printf("outside function: (%d, %d)n", node->x, node->y);
node = node->next;
}
return 0;
}
行
previous->next = &(struct Item){ .x = (i*2), .y = (i*3), .next = NULL };
存储退出for
循环时超出范围的本地堆栈变量的地址。在此之后,访问内存会导致未定义的行为。一个可能的问题是,程序的其他部分将写入相同的堆栈位置。
您可以通过为列表元素动态分配内存来解决此问题
previous->next = malloc(sizeof(*previous->next));
if (previous->next == NULL) {
/* handle out of memory */
}
*previous->next = (struct Item){ .x = (i*2), .y = (i*3), .next = NULL };
如果执行此操作,请注意,您需要调用free
,以便稍后将此内存返回到系统。