对于这个源代码有多长,我提前道歉。我不完全确定我在哪里出错了。我写了一个二叉树实现和一些树遍历的函数。向树中添加一项是可行的,但添加多项会导致分段错误。DDD 在 backtrace 中列出了几个函数:命名为 isfull、addToTree 和 isEmpty。
该程序跨越三个源文件(对不起)。
/*----------------------------------Tree.h----------------------------------*/
#ifndef TREE
#define TREE
#define MAXHEIGHT 4
typedef struct cat{
char *name;
int age;
}Item;
typedef struct node{
Item thing;
}Node;
typedef struct tree{
Node *root;
struct tree *left, *right;
int leafcount;
}Tree;
void initializeTree(Tree *);
void closeTree(Tree *);
int isEmpty(const Tree *);
int isFull(const Tree*);
Tree *searchTree(Item *thing, Tree *t, int (*)(const Item *, const Item *));
int addToTree(Item *, Tree *, int (*)(const Item *, const Item *));
int removeFromTree(Item *, Tree *);
int itemComp(const Item *, const Item *);
#endif
/*----------------------------------Tree.c----------------------------------*/
#include "Tree.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
Node *copyToNode(Item *);
/*Definition: Tree
Node *root;
int leafcount; */
Node *copyToNode(Item *thing){
Node *tmp = malloc(sizeof(Node));
if(tmp == NULL)
return tmp;
tmp->thing = *thing;
return tmp;
}
void initializeTree(Tree *t){
t->root = NULL;
t->right = t->left = NULL;
t->leafcount = 0;
}
int isEmpty(const Tree *t){
return t->root == NULL;
}
int isFull(const Tree *t){
return t->leafcount == (int)pow(2,MAXHEIGHT) - 1;
}
int addToTree(Item *thing, Tree *t, int (*fp)(const Item *, const Item *)){
if(isFull(t))
return 0;
if(isEmpty(t)){
Node *current = copyToNode(thing);
if(current == NULL){
puts("Couldn't copy to tree!");
return 0;
}
t->root = current;
t->leafcount++;
return 1;
}
if(fp(thing, &t->root->thing) <= 0)
return addToTree(thing, t->left, fp);
else
return addToTree(thing, t->right, fp);
}
Tree *searchTree(Item *thing, Tree *t, int (*fp)(const Item *, const Item *)){
int temp;
if(t->root == NULL)
return NULL;
else if((temp = fp(&t->root->thing, thing)) == 0)
return t;
else if(temp = -1)
return searchTree(thing, t->left, fp);
else
return searchTree(thing, t->right, fp);
}
int removeFromTree(Item *thing, Tree *t){
/*Tree *tmp = searchTree(thing, t);
Not finished*/
}
void closeTree(Tree *t){
return;
}
/*------------------------------TreeDriver.c-------------------------------*/
#include "Tree.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXNAME 30
int promptUser(void);
int itemComp(const Item *, const Item *);
Item * createUserItem();
int main(){
int userChoice;
Item * userItem = NULL;
Tree userTree;
initializeTree(&userTree);
do{
userChoice = promptUser();
switch(userChoice){
case 1:
puts("Enter cat information to add");
userItem = createUserItem();
if(addToTree(userItem, &userTree, itemComp))
puts("Cat successfully added!");
else
puts("Could not add cat!");
break;
case 2:
puts("Enter cat information to search for");
userItem = createUserItem();
if(searchTree(userItem, &userTree, itemComp))
puts("Cat found!");
else
puts("Cat not found!");
break;
case 3:
if(isEmpty(&userTree))
puts("Tree is empty!");
else
puts("Tree is not empty!");
break;
case 4:
if(isFull(&userTree))
puts("Tree is full!");
else
puts("Tree is not full!");
break;
case 0:
break;
default:
puts("Not an option!");
break;
}
}while(userChoice);
}
int itemComp(const Item *thing_one, const Item *thing_two){
int comparison;
if(comparison = strcmp(thing_one->name, thing_two->name))
return comparison;
return !(thing_one->age == thing_two->age);
}
int promptUser(){
int tmp;
puts("--------MENU---------");
puts("1. Create cat");
puts("2. Search for cat");
puts("3. Check empty");
puts("4. Check full");
puts("0. Quit");
scanf("%d", &tmp);
while(getchar() != '\n')
;
return tmp;
}
Item * createUserItem(){
Item *tmp = malloc(sizeof(Item));
static char namebuf[MAXNAME];
printf("Enter cat name: ");
if(fgets(namebuf, MAXNAME, stdin) == NULL)
return NULL;
tmp->name = malloc(strlen(namebuf));
strcpy(tmp->name, namebuf);
printf("Enter cat age:\t");
scanf("%d", &tmp->age);
while(getchar() != '\n')
;
return tmp;
}
无论如何,我不确定如何解释调试器的回溯。我哪里做错了?它可能与我如何处理在驱动程序文件中为用户输入创建一个虚拟项目有关吗?我不认为我处理得很好(或者这个程序的其余部分)。
谢谢