编写链表实现时遇到C指针问题

时间:2017-07-16 08:51:28

标签: c pointers

我最近又回到了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

由于

2 个答案:

答案 0 :(得分:3)

您提供的转储显示{<1}}的值在您执行

后发生了变化
(*linked_list)->last

但是这行代码不会改变(*linked_list)->last->next = new; (至少,它不应该改变)。

对这种“神奇”行为的可能解释包括

  1. (*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会返回不正确的值(指针的大小而不是结构的一面)类型)。这可以解释记忆的未定位。

  2. sizeof(linked_list)不是正确初始化的指针。它指向一些不可预测的位置。因此,(*linked_list)->last恰好与*(*linked_list)->last等等的内存位置重叠(见上文)。

  3. 您运行的代码不是您在此处发布的代码。

答案 1 :(得分:-3)

答案是我在使用malloc时需要使用struct关键字:

linked_list_entry* new = malloc(sizeof(struct linked_list_entry));