//这段代码把二叉树的顺序储存转化为链式储存,参数*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 ;
}
7 个解决方案
#1
释放前看看 queue 的值与 生成时是否一样
#2
刚才检查过了。。。queue的值没有变,依旧还是那个地址。。。。
#3
原因很多,比如你的指针访问了越界(可能使用时没什么问题),让系统误认为该空间属于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;
}
#4
for( i = 2; i < list[0].data; i++,x++) // list[0].data 的值 = 数据总数+1
//越界访问应该是没有的,要是越界访问,调试的时候应该会出错。。不过你说的第二点,
//我感觉比较像出错原因。。。考虑到p1[10]=p2;//访问越界 不会发生。。
//就不太清楚了,我再看一下。。。多谢提示
#5
崩溃的时候在弹出的对话框按相应按钮进入调试,按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;
}
#6
调试的时候一点问题都没有怎么办?
#1
释放前看看 queue 的值与 生成时是否一样
#2
刚才检查过了。。。queue的值没有变,依旧还是那个地址。。。。
#3
原因很多,比如你的指针访问了越界(可能使用时没什么问题),让系统误认为该空间属于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;
}
#4
原因很多,比如你的指针访问了越界(可能使用时没什么问题),让系统误认为该空间属于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;//访问越界 不会发生。。
//就不太清楚了,我再看一下。。。多谢提示
#5
崩溃的时候在弹出的对话框按相应按钮进入调试,按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;
}
#6
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。
[/code]
调试的时候一点问题都没有怎么办?
#7
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。
[/code]
调试的时候一点问题都没有怎么办?
Win XP:
drwtsn32 -i
运行你的程序
drwtsn32
Win7:
http://www.nirsoft.net/utils/app_crash_view.html