Ошибка сегментации - отображение дерева - PullRequest
0 голосов
/ 18 ноября 2009

Я получаю segfault при вызове viewTree (root);

    struct treeElement {
        unsigned long weight;
        unsigned short id;
        char chr;
        struct treeElement *lchild, *rchild, *parent;
    };

    typedef struct treeElement node;

    node *root;

    //INITIALIZE TREE
    void initTree() {
        root = malloc(sizeof(node));
        currentNYT = root;
    } //initTree

    //VIEW TREE
    void viewTree(node *tree) {
        printf("%5d%5d%5d%5d%5c%lu", tree->id, tree->parent->id, tree->lchild->id, tree->rchild->id, tree->chr, tree->weight);
        viewTree(tree->lchild);
        viewTree(tree->rchild);
    }

//ADD NODE
void addNode(char newNodeChr) {
    node *newNYT, *newExternal;
    newNYT = malloc(sizeof(node));
    newNYT->id=maxNodes-idCount; idCount++;
    newNYT->chr='\0';
    newNYT->weight=0;
    newNYT->parent=currentNYT;
    newNYT->lchild=newNYT->rchild=NULL;
    newExternal = malloc(sizeof(node));
    newExternal->id=maxNodes-idCount;
    newExternal->chr=newNodeChr;
    newExternal->weight=1;
    newExternal->parent=currentNYT;
    newExternal->lchild=newExternal->rchild=NULL;
    currentNYT->lchild = newNYT;
    currentNYT->rchild = newExternal;
    currentNYT=newNYT;
} //addNode

int main()
{
    initTree();
    addNode('a');
    addNode('b');
    viewTree(root);

    getchar();

    return 0;
}

Ответы [ 3 ]

2 голосов
/ 18 ноября 2009

Есть ли у корневого узла родительский узел? Есть ли у дочерних листовых узлов левый и правый дочерние узлы?

Я думаю, что большая часть вашей проблемы заключается в вашем утверждении printf - вы не проверяете, существует ли какой-либо объект, к которому вы обращаетесь, на самом деле, прежде чем пытаться напечатать их id s. Добавьте туда несколько операторов if и посмотрите, поможет ли это.

1 голос
/ 18 ноября 2009

В вашем viewTree(node *tree) вы не проверяете, является ли tree значением null или нет. Определенный рецепт для segfault, когда вы пытаетесь получить доступ к tree->id, когда tree равно null.

null будет передано для поддерева в рекурсивном вызове.

РЕДАКТИРОВАТЬ: Как правило, вы проверяете null каждый раз, когда вам нужен доступ к члену объекта. Таким образом, tree != null перед чтением tree->id и tree->lchild != null перед чтением tree->lchild->id должны быть обеспечены.

0 голосов
/ 18 ноября 2009

Не просто выделите корневой узел, но инициализируйте его, особенно указатели на братьев и сестер и на родителя (установите их в NULL). Вы используете неинициализированные указатели при добавлении узлов.

...