二叉树的创建的内存问题

来源:互联网 发布:安卓源码编译教程 编辑:程序博客网 时间:2024/06/05 05:26

下面的二叉树创建代码是有问题的:

#include <stdio.h>#include <stdlib.h>#define MAX_LEN 50#define ElemType char#define Status int#define OK 1#define ERROR 0#define OVERFLOW -1typedef struct Node{ElemType data;struct Node *lchild,*rchild;}BiTreeNode,*BiTree;/*递归创建一棵二叉树*/void CreateBiTreeByRec(BiTree &T){char ch;scanf("%c",&ch);if(ch=='#'){T = NULL;}else{if(!(T = (BiTree)malloc(sizeof(BiTreeNode)))){exit(OVERFLOW);}T->data = ch;CreateBiTreeByRec(T->lchild);CreateBiTreeByRec(T->rchild);}}/*前序非递归创建二叉树*/void CreateBiTreeByPreNoRec(BiTree &T){char ch;BiTree s[MAX_LEN]={NULL},p=NULL;int top = 0;//栈顶指针scanf("%c",&ch);if('#'==ch){T = NULL;}else{if(!(T = (BiTree)malloc(sizeof(BiTreeNode)))){exit(OVERFLOW);}T->data = ch;s[++top] = T;p = T;}while(top!=0){scanf("%c",&ch);if(ch=='\n'){break;}if(ch!='#'){BiTree r;if(!(r = (BiTree)malloc(sizeof(BiTreeNode)))){exit(OVERFLOW);}r->data = ch;p->lchild = r;p = r;s[++top] = r;}else{p->lchild = NULL;scanf("%c",&ch);while(ch=='#'){p->rchild = NULL;p = s[top--];scanf("%c",&ch);}if(top!=0){p = s[top--];BiTree r;if(!(r = (BiTree)malloc(sizeof(BiTreeNode)))){exit(OVERFLOW);}r->data = ch;p->rchild = r;p = r;s[++top] = r;}}}}
当你用下面的遍历方法遍历时就会报内存错误:

/*前序递归遍历*/void PreOrderRec(BiTree &T){if(NULL!=T ){printf("%c ",T->data);PreOrderRec(T->lchild);PreOrderRec(T->rchild);}}/*前序非递归遍历*/void PreOrder(BiTree &T){BiTree s[MAX_LEN]={NULL},p=NULL;int top = 0;p = T;do{while(p!=NULL ){printf("%c ",p->data);s[++top] = p;p = p->lchild;}if(top==0){break;}else{p = s[top--];p = p->rchild;}}while(top!=0);}

于是你就开始调试,终于发现了问题:

就是那个0xcdcdcdcd

其实报错不是在创建的时候,而是在遍历时:


当T访问到这个野指针时,就报错了

那么这个是什么指针呢?百度知道

而我是怎么解决的呢,很简单遍历时加个判断条件:

if(T!=NULL && T!=(BiTree)0xcdcdcdcd)


while(p!=NULL && p!=(BiTree)0xcdcdcdcd)
这样是不会再报错的,但问题没有解决,因为:

在 Debug 模式下,VC 会把未初始化的栈内存上的指针全部填成 0xcccccccc ,当字符串看就是 “烫烫烫烫……”,会把未初始化的堆内存上的指针全部填成 0xcdcdcdcd

但是,用malloc分配的内存为何还要用memset再初始化一次?

平时都没这么做呀!

所以暂时先放一放

时隔一星期,

现在这个问题已经解决:

问题出在分配的r指针的左子树和右子树没有置为空:

BiTree r;if(!(r = (BiTree)malloc(sizeof(BiTreeNode)))){exit(OVERFLOW);}r->data = ch;p->lchild = r;p = r;s[++top] = r;


应该修改为:

BiTree r;if(!(r = (BiTree)malloc(sizeof(BiTreeNode)))){exit(OVERFLOW);}r->data = ch;r->lchild = NULL;r->rchild = NULL;p->lchild = r;p = r;s[++top] = r;

这样结果就不会报错了。

所以细心和能力很重要呀。

1 0