###前提条件
2分木のコードを書いています。
preorderは行きがけ順
inorderは通りがけ順
postorderは帰りがけ順
で各ノードのラベルを出力するプログラムを書こうとしています.
create_tree内で作成したノードのラベルを出力できるのを確認しているのですが,
他のプログラムでは下の実行結果のようになってしまいます。
原因がわからないので,原因または原因の探し方を教えて頂きたいです.
よろしくお願いします.
###実行結果
***:/mnt/c/Users/user/Desktop/***$ make cc -c -o binarytree.o binarytree.c cc binarytree.o main_binarytree.o -o binarytree ***:/mnt/c/Users/user/Desktop/***$ ./binarytree F I D G A L C preorder: (null)(null) inorder: (null)(null) postorder: (null)(null)
###コード
<binarytree.h>
c
1#ifndef INCLUDE_GUARD_BINARYTREE_H 2#define INCLUDE_GUARD_BINARYTREE_H 3 4typedef struct node { 5 char *label; 6 struct node *left; 7 struct node *right; 8} Node; 9 10Node *create_tree(char *label, Node *left, Node *right); 11void preorder(Node *n); 12void inorder(Node *n); 13void postorder(Node *n); 14void display(Node *n); 15void breadth_first_search(Node *n); 16int height(Node *n); 17void delete_tree(Node *n); 18 19#endif // INCLUDE_GUARD_BINARYTREE_H 20
<binarytree.c>
c
1#include <stdio.h> 2#include <stdlib.h> 3#include "binarytree.h" 4 5Node *create_tree(char *label, Node *left, Node *right) 6{ 7 Node *root = (Node*)malloc(sizeof(Node)); 8 9 root->left = (Node*)malloc(sizeof(Node)); 10 root->right = (Node*)malloc(sizeof(Node)); 11 root->label = (char*)malloc(sizeof(char)); 12 13 printf("%s",label); 14 return root; 15} 16 17void preorder(Node *n) 18{ 19 if (n != NULL) 20 { 21 printf("%s",n->label ); 22 preorder(n->left); 23 preorder(n->right); 24 } 25} 26 27void inorder(Node *n) 28{ 29 if (n != NULL) 30 { 31 inorder(n->left); 32 printf("%s",n->label ); 33 inorder(n->right); 34 } 35} 36 37void postorder(Node *n) 38{ 39 if (n != NULL) 40 { 41 postorder(n->left); 42 postorder(n->right); 43 printf("%s",n->label ); 44 } 45} 46
<main_binarytree.c>
c
1#include <stdio.h> 2#include <stdlib.h> 3#include "binarytree.h" 4 5int main(void) { 6 // Build a binary tree 7 Node *f = create_tree("F", NULL, NULL); 8 Node *i = create_tree("I", NULL, NULL); 9 Node *d = create_tree("D", f, NULL); 10 Node *g = create_tree("G", NULL, NULL); 11 Node *a = create_tree("A", i, d); 12 Node *l = create_tree("L", NULL, g); 13 Node *c = create_tree("C", a, l); 14 15 printf("preorder: "); 16 preorder(c); 17 printf("\n"); 18 19 printf("inorder: "); 20 inorder(c); 21 printf("\n"); 22 23 printf("postorder: "); 24 postorder(c); 25 printf("\n"); 26 27return EXIT_SUCCESS; 28}
Makefile
1binarytree: binarytree.o main_binarytree.o
原因はもう分かっているようなので、原因の探し方だけ。
今回のケースでは最初にNULLが検出されているのが、
preorder: (null)(null)
これなので、まずはpreorderを調べます。
関数preorder()の中ではn->labelを参照してprintf()しています。これをデバッガで追っかけてみます。
最初にmain関数のcを引数にpreorder()が呼ばれますが、このときのnは
n->label: どこかのアドレス 内容は""
n->left: どこかのアドレス
n->left->label: 0x0
n->right: どこかのアドレス
n->left->label: 0x0
となっています。すると、cのlabelを出力するときは""なので何も出力されず、n->leftで再帰呼び出しした際に0x0なので(null)が出力され、n->rightで再帰呼び出しした際も0x0で(null)が出力されてしまっていたことが分かります。
次はlabelに""やNULLが入っていた原因を追うことになります。
c->labelやc->left or right->labelを設定しているのはcreate_tree()関数なので、そちらを見てみます。
ここもデバッガで追っかければ分かるのですが、コードを見るだけでlabelはもちろん、メンバ変数に引数で渡された値を全く代入していないことが分かります。そのため、mallocで確保された領域がそのまま使用されており、確保された領域が偶然(?)0だったため、""だったり、NULLだったりしていたということです。
対策としては引数で渡された値を設定すればいいかと思います。渡されたポインタをそのまま代入するか、コピーした内容を作成し、それを設定するかはプログラムの仕様で決めることになります。引数で渡された変数の生存期間と、引数で渡された変数の中身を変更することによりTreeの内容の変更を許すかどうか?によって決まります。
回答2件
あなたの回答
tips
プレビュー