2017-07-16 62 views
-2

最近我又回到了C编程中,并且遇到了一些我正在编写的链表实现的问题。编写链表实现时遇到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) 

任何想法,为什么最后指针变为新新指针变为NULL?

感谢

+0

是^新^不是保留字? – MKR

+3

@ManojKumarRai不,''new'不是C中的保留字。你用C++混淆了。 – Gilles

+0

'* linked_list'指针的值是什么?将其添加到转储。你如何为'linked_list'分配内存? – AnT

回答

-3

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

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

呃......为什么? 'linked_list_entry'本身就是一个完全有效的类型名称。 – AnT

+3

这对你显示的代码没有任何影响。也许你正在运行另一个版本的代码? – Gilles

+0

它的确如此,请参阅我刚才写的以下测试: printf(“%d vs%d \ n”,sizeof(linked_list),sizeof(struct linked_list)); 8 vs 24 奇怪! – Jason

3

您提供显示,(*linked_list)->last值已更改你做

(*linked_list)->last->next = new; 
后转储

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

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

  1. **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)将返回不正确的值(指针的大小而不是结构类型的一侧)。这将解释内存的未配置。

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

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