下列程序运行时会崩溃,请找出错误并改正,并且说明原因。
#include <stdio.h>
#include <malloc.h>
typedef struct
{
TNode* left;
TNode* right;
int value;
} TNode;
TNode* root=NULL;
void append(int N);
int main()
{
append(63);
append(45);
append(32);
append(77);
append(96);
append(21);
append(17); // Again, 数字任意给出
}
void append(int N)
{
TNode* NewNode=(TNode *)malloc(sizeof(TNode));
NewNode->value=N;
if(root==NULL)
{
root=NewNode;
return;
}
else
{
TNode* temp;
temp=root;
while((N>=temp.value && temp.left!=NULL) || (N<temp. value && temp. right!=NULL))
{
while(N>=temp.value && temp.left!=NULL)
temp=temp.left;
while(N<temp.value && temp.right!=NULL)
temp=temp.right;
}
if(N>=temp.value)
temp.left=NewNode;
else
temp.right=NewNode;
return;
}
}
解答:
//下列程序运行时会崩溃,请找出错误并改正,并且说明原因。
/*
此程序的功能是完成一个有序二叉树的建立,使得左子树结点的值小于根结点,
右子树大于根结点. 题目程序中结构体定义的地方有误,在TNode名字出现之前,
就在结构体内使用TNode,将导致编译错误.另外题目中append函数中的所有temp的点号操作符都应改成->,
因为temp是个指针.至于题目中所说的程序在运行时崩溃出现在append函数中的对temp->left和temp->right操作时候,
因为每创建一个新结点的时候都没将left和right成员初始化为空指针,会导致append函数中的while循环访问到非法内存,
从而导致程序崩溃. 为了方便测试,添加了函数print_tree打印树的结点内容,
另外补充了一个函数free_tree来释放动态分配的内存.修改后的程序如下:
*/
#include <iostream>
using namespace std;
//typedef struct{ //错误1 TNode名字出现前,就在结构内使用TNode将导致编译错误
typedef struct TNode{ //应该这样写
TNode* left;
TNode* right;
int value;
}TNode;
TNode* root=NULL;
void append(int N);
void free_tree(TNode *root);
void print_tree(TNode *root);
int main()
{
append(63);
append(45);
append(32);
append(77);
append(96);
append(21);
append(17); // Again, 数字任意给出
print_tree(root);
cout<<"\n memory released !\n";
free_tree(root);
system("pause");
return 0;
}
void append(int N)
{
TNode* NewNode=(TNode *)malloc(sizeof(TNode));
if (!NewNode)
{
cout<<"memory alloc failure!\n";
exit(1);
}
NewNode->value=N;
//NewNode->left;
//NewNode->right; //错误2 没有初始化新结点的left和right成员为空指针,
//导致append函数中while循环访问到非法内存,从而导致运行时崩溃
NewNode->left=NULL;
NewNode->right=NULL;
if(root==NULL)
{
root=NewNode;
return;
}
else
{
TNode* temp;
temp=root;
//while((N>=temp.value && temp.left!=NULL) || (N<temp. value && temp. right!=NULL))
//错误3 temp是指针,则下面引用成员应该使用->而不是.(点)
while((N>=temp->value && temp->left!=NULL) || (N<temp->value&&temp->right!=NULL))
{
while(N>=temp->value && temp->left!=NULL)
temp=temp->left;
while(N<temp->value && temp->right!=NULL)
temp=temp->right;
}
if(N>=temp->value)
temp->left=NewNode;
else
temp->right=NewNode;
return;
}
}
//释放内存函数
void free_tree(TNode *root){
if (!root->left && !root->right)
{
free(root);
return;
}
if (root->left)
{
free_tree(root->left);
}
else{
free_tree(root->right);
}
}
//打印函数
void print_tree(TNode *root){
if (!root->left && !root->right)
{
cout<<root->value<<" ";
return;
}
if (root->right)
print_tree(root->right);
cout<<root->value<<" ";
if (root->left)
{
print_tree(root->left);
}
}