我最近又回到了C编程中,并且在编写链接列表时遇到了一些问题。
以下是我的结构定义:
typedef struct linked_list_entry {
struct linked_list_entry *next;
struct linked_list_entry *prev;
void* data;
} linked_list_entry;
typedef struct linked_list {
uint32 count;
struct linked_list_entry *first;
struct linked_list_entry *last;
} linked_list;
以下是有问题的代码:
int linked_list_add_entry(linked_list** linked_list, void* data)
{
linked_list_entry* new = malloc(sizeof(linked_list_entry));
...
DPRINT("last(%p), new (%p)\n", (*linked_list)->last, new);
(*linked_list)->last->next = new;
DPRINT("(*linked_list)->last(%p)->next (%p)\n", (*linked_list)->last, (*linked_list)->last->next);
使用调试输出:
data-types/linked-list.c:37:linked_list_add_entry(): last(0x7fa497402790), new (0x7fa4974027b0)
data-types/linked-list.c:39:linked_list_add_entry(): (*linked_list)->last(0x7fa4974027b0)->next (0x0)
知道为什么最后一个指针变为new并且新指针变为NULL
?
由于
答案 0 :(得分:3)
您提供的转储显示{<1}}的值在您执行
后发生了变化(*linked_list)->last
但是这行代码不会改变(*linked_list)->last->next = new;
(至少,它不应该改变)。
对这种“神奇”行为的可能解释包括
(*linked_list)->last
未正确分配。分配的内存太少
**linked_list
对象。因此,**linked_list
恰好与*(*linked_list)->last
的内存位置重叠。这就是为什么上述作业似乎也会改变**linked_list
。即由于前面提到的指针问题(*linked_list)->last
和(*linked_list)->last
在内存中占据相同的位置。
这样的事情可能发生,例如,当为对象分配不正确(不足)的内存量时。在这种情况下,问题出在调用代码中。它提供了一个“损坏”列表作为输入。
调用代码如何为(*linked_list)->last->next
本身分配内存?请注意,在此函数中,您使用名称linked_list
作为函数参数,从而隐藏了类型linked_list
的名称。如果你在“其他”函数中做了类似的事情 - 分配linked_list
对象本身的那个 - 然后尝试在那里使用linked_list
会返回不正确的值(指针的大小而不是结构的一面)类型)。这可以解释记忆的未定位。
sizeof(linked_list)
不是正确初始化的指针。它指向一些不可预测的位置。因此,(*linked_list)->last
恰好与*(*linked_list)->last
等等的内存位置重叠(见上文)。
您运行的代码不是您在此处发布的代码。
答案 1 :(得分:-3)
答案是我在使用malloc时需要使用struct关键字:
linked_list_entry* new = malloc(sizeof(struct linked_list_entry));