我正在尝试创建一个删除整个列表的函数,但我一直收到错误。 除了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时出现此错误)
答案 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)
。(NOD*)
。 (谷歌“malloc类型转换”是一个清单的理由,但足以说,它是不必要的,并且很可能会破坏你的代码并在以后隐藏错误。)malloc
是多余的,但在r = NULL
之后进入,清除指针是个好习惯,所以这不错: - )