删除C中的链表

时间:2011-12-09 23:19:36

标签: c list free

我正在尝试创建一个删除整个列表的函数,但我一直收到错误。 除了cleaner()函数之外,一切都有效。

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

struct node{
    int n;
    struct node *next;
};

typedef struct node NOD;

NOD *create_first_node(int i)
{
    NOD *q;
    q=(NOD*)malloc(sizeof(NOD*));
    q->n=i;
    q->next=NULL;
    return q;
}

NOD * add_to(NOD *x)
{
    NOD *q;
    q=(NOD*)malloc(sizeof(NOD*));
    q->n=rand();
    x->next=q;
    q->next=NULL;
    return q;
}

void show_list(NOD *p)
{
    printf("root");
    while(p->next){
        printf(" -> %d",p->n);
        p=p->next;
    }
    printf("\n");
}


void cleaner(NOD *p)
{
    NOD *r;
    while(p)
    {
        r=p;
        p=r->next;
        free(r);
        r=NULL;
    }
}


int main()
{
    int i;
    NOD *root,*c,*r;
    root=create_first_node(1);
    c=r=root;
    c=add_to(root);
    for(i=0;i<10;i++)
    {
        r=c;
        c=add_to(r);
    }
    show_list(root);
    //cleaner(root);
    system("pause");
    return 0;
}

的NetBeans:

收到的信号:带sigcode的SIGTRAP(?)? (?) 从过程:? 对于程序列表,pid -1

您可以丢弃信号或转发信号,然后您可以继续或暂停该过程 要控制捕获或忽略哪些信号,请使用Debug-> Dbx Configure


Visual Studio:

调试错误!

HEAP CORRUPTION DETECTED:正常阻止(#57)之后 0x00393230 CRC检测到应用程序在堆缓冲区结束后写入内存。

(每当cleaner()尝试释放列表项时,我会在#57,#58,...,#68时出现此错误)

3 个答案:

答案 0 :(得分:3)

我认为

q=(NOD*)malloc(sizeof(NOD*));应为q=(NOD*)malloc(sizeof(NOD));

你需要为整个节点分配足够的内存,但是你只需要为指针分配足够的内存。

答案 1 :(得分:1)

我承认我刚刚浏览了你的代码,但是当你创建和添加节点时,你会做一个

 q=(NOD*)malloc(sizeof(NOD*));

但你应该做一个

 q=(NOD*)malloc(sizeof(NOD));

否则,您只需为NOD *分配空间,该空间为4或8个字节,具体取决于您的系统(假设它是普通PC)。但是你的NOD结构将至少有8或16个字节(再次取决于你的系统和你的int的大小,假设你使用普通的PC硬件)。

因此,当您访问 n 成员时,您已经处于勉强合法的境地,但是当您稍后触摸下一个成员时,您处于未定义的行为中,并且幸运的是,你的软件只会导致堆损坏......

答案 2 :(得分:0)

  • NULL不是必然与0相同。通常是,但你“不应该”认为它会是。因此,while(p)很危险...请使用while (NULL != p)(p != NULL): - )
  • 使用malloc时,您要分配NOD*的大小,指针;你打算用sizeof(NOD)
  • 另外,请勿在{{1​​}}的返回时添加类型(NOD*)。 (谷歌“malloc类型转换”是一个清单的理由,但足以说,它是不必要的,并且很可能会破坏你的代码并在以后隐藏错误。)
  • malloc是多余的,但在r = NULL之后进入,清除指针是个好习惯,所以这不错: - )