堆损坏,求解释

小白也疯狂 2013-11-24 04:51:45

//这段代码把二叉树的顺序储存转化为链式储存,参数*list是形如:ABCD#ED的串,#表示NULL
//在这段代码的最后,free(queue) 导致了堆损坏,分析了一下,觉得不会出错。。。在调试的时候,没有出错,直接运行程序,就直接出错了,求解释
node * listTolink( node *list )
{
node *root = NULL;
node *p = NULL ;
node **queue = NULL;
int x = 0 ;
int rear = 0 ;
int i ;

queue = (node **)malloc(sizeof(node * ) * list[0].data) ;
root = (node *)malloc(sizeof(node));
queue[0] = root ;
*root = list[1];

for( i = 2; i < list[0].data; i++,x++)
{
if ( list[i].data != '#' )
{
p = (node *)malloc(sizeof(node));
*p = list[i] ;
queue[x]->lchild = p ;
queue[++rear] = p ;
}
else
queue[x]->lchild = NULL ;

i++ ; // 判断右孩子

if ( list[i].data != '#' )
{
p = (node *)malloc(sizeof(node));
*p = list[i] ;
queue[x]->rchild = p ;
queue[++rear] = p ;
}
else
queue[x]->rchild = NULL ;

}
free(queue) ;

return root ;
}
...全文
310 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2013-11-25
  • 打赏
  • 举报
回复
引用 6 楼 u010749411 的回复:
[quote=引用 5 楼 zhao4zhong1 的回复:] 崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 [/code]
调试的时候一点问题都没有怎么办?[/quote] Win XP: drwtsn32 -i 运行你的程序 drwtsn32 Win7: http://www.nirsoft.net/utils/app_crash_view.html
小白也疯狂 2013-11-25
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 [/code]
调试的时候一点问题都没有怎么办?
赵4老师 2013-11-25
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}
小白也疯狂 2013-11-24
  • 打赏
  • 举报
回复
引用 3 楼 Adol1111 的回复:
原因很多,比如你的指针访问了越界(可能使用时没什么问题),让系统误认为该空间属于malloc的空间,然后当你free这个指针的时候,实际上释放了一块未分配的空间,就导致堆破坏了。 如下代码:
int main()
{
	int ** p1=(int**)malloc(sizeof(int)*10);
	int *p2=(int *)malloc(sizeof(int));
	p1[10]=p2;//访问越界
	free(p1);//误以为p1[10]也是malloc地址,一起释放,导致free了无效空间造成堆破坏
	return 0;
}
 for( i = 2; i < list[0].data; i++,x++) // list[0].data 的值 = 数据总数+1
//越界访问应该是没有的,要是越界访问,调试的时候应该会出错。。不过你说的第二点,
//我感觉比较像出错原因。。。考虑到p1[10]=p2;//访问越界  不会发生。。
//就不太清楚了,我再看一下。。。多谢提示
Adol1111 2013-11-24
  • 打赏
  • 举报
回复
原因很多,比如你的指针访问了越界(可能使用时没什么问题),让系统误认为该空间属于malloc的空间,然后当你free这个指针的时候,实际上释放了一块未分配的空间,就导致堆破坏了。 如下代码:
int main()
{
	int ** p1=(int**)malloc(sizeof(int)*10);
	int *p2=(int *)malloc(sizeof(int));
	p1[10]=p2;//访问越界
	free(p1);//误以为p1[10]也是malloc地址,一起释放,导致free了无效空间造成堆破坏
	return 0;
}
小白也疯狂 2013-11-24
  • 打赏
  • 举报
回复
刚才检查过了。。。queue的值没有变,依旧还是那个地址。。。。
AnYidan 2013-11-24
  • 打赏
  • 举报
回复
释放前看看 queue 的值与 生成时是否一样

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧