C中双向链表的内存故障

时间:2014-09-17 15:30:25

标签: c doubly-linked-list

我试图写一个双向链表。以下代码通过了我的测试,但我在next方向和prev方向为新节点分配内存。具体来说,问题是我认为我不应该在current函数中分配push,因为这些节点已经在new的过去迭代中分配了。但是,如果我设置new->prev = current而未分配current,则会出现细分错误。请注意,如果我没有分配current或使用->prev,则下面的代码可以正常用作单链表。

删除malloc for current后,代码在打印测试后会出现段错误(首次使用prev时)。

#include <stdlib.h>
#include <stdio.h>

struct list{
    int value;
    struct list *next;
    struct list *prev;
};
struct list *head;
struct list *tail;

void init(int val){
    head = (struct list *)malloc(sizeof(struct list *));
    head->value = val;
    head->next = NULL;
    head->prev = NULL;

    tail = malloc(sizeof(struct list *)); 
    tail->value = val;
    tail->next = NULL;
    tail->prev = NULL;

}

void push(int val){
     struct list *new;
     struct list *current;
     new = (struct list *)malloc(sizeof(struct list *)); //allocate memory space for next side
     current = (struct list *)malloc(sizeof(struct list *)); //allocate memory space for prev side
     new->value = val;
     new->next = NULL;
     current = head;
     while(current->next!=NULL){current = current->next;}
     new->prev = current;
     current->next = new;
     tail = new;
 }

 int main(){
     printf("init with 10\n");
     init(10);
     printf("pushing 11\n");
     push(11);
     printf("pushing 12\n");
     push(12);
     printf("pushing 13\n");
     push(13);
     printf("testing\n");
     printf("2-1 %d\n",head->next->prev->value);
     printf("3-1 %d\n",head->next->next->prev->value);
     printf("h4-1 %d\n",head->next->next->next->prev->value);
     printf("t-1 %d\n",tail->prev->value);
     printf("t-2 %d\n",tail->prev->prev->value);
     printf("t %d\n",tail->value);
 }

3 个答案:

答案 0 :(得分:3)

根据我上面的评论:

void init(int val){
    head = malloc(sizeof *head);
    head->value = val;
    head->next = NULL;
    head->prev = NULL;
    tail = head;
}

void push(int val){
     struct list *new;
     new = malloc(sizeof *new); //allocate memory space for next side
     new->value = val;
     new->next = NULL;
     new->prev = tail;
     tail->next = new;
     tail = new;
 }

您还应该确保malloc没有返回NULL,但错误处理会让所有事情变得混乱!

答案 1 :(得分:2)

一个明显的错误是您在指针大小位中分配内存,而不是列表节点的大小。尝试将mallocs更改为:

ptr = malloc(sizeof(struct list));  // note the missing '*'

我敢打赌,这将彻底解决你的大部分记忆问题。但并非所有,例如,在分配电流后,你仍然会通过覆盖电流来进行内存泄漏(尽管如其他海报所说的那样,它并不是必需的)

答案 2 :(得分:1)

我认为你不应该每次推送都分配一个新列表(这里current);只需指出head即可。在这里,您只需分配一个列表,然后在指向此列表的指针指向您的head之后。所以没有必要分配它。

分配创建了程序可写的足够空间,指针只存储地址,这就是你想要的地址,只要你迭代current而不是你的head,你的指针就不会改变tail->prev

我本可以在这些解释中迷失自己,也许会失去你的问题的目的,但希望这会对你有帮助。

哦,最后一件事,也许你应该head点{{1}}。

但是我仍然不明白为什么你在你的init中分配2个节点而不是一个接一个地将它们推到你的头上