私は20の質問に似たプログラムを実装しようとしています。このプログラムでは、質問のテキストファイルと回答の推測がロードされ、char配列にコピーされます(分割するために新しいスペース行が「/0」に置き換えられます)個々の文字列への質問)。テキストファイルがコピーされた後、配列は正常に機能します。ツリー構造は、フレーズを yes/no 質問ツリーに編成するように設定されています。左側の子は yes 応答で、右側は no 応答であり、葉は、プログラムが最後に推測するために使用する推測です。
私が抱えている問題は、ツリーを構築した後 (InitTree から treeBuilder を呼び出す)、テキスト ファイルからのフレーズがコピーされた配列の内容が破損したことです。
InitTree を呼び出す前は、配列の内容は次のようになっています。
毛むくじゃらですか?鳴きますか?猫 犬 牙はありますか?大きな耳はありますか?ゾウ サイ ワニ
呼び出した後、次のようになります。
毛むくじゃらですか?-???` ?p ?a 犬 牙はありますか? 大きな耳はありますか?ゾウ サイ ワニ
どこで機能しなくなるかをテストしてきました.treeBuilder内では、配列のすべての要素はそのままですが、treeBuilderへの関数呼び出しが終了するとすぐに、配列が破損します. メモリを割り当てるたびに calloc を使用してメモリを保護しようとしましたが、文字配列を静的にすることでさえ、これが発生したのと同様の状況で機能しました。しかし、私の予防策のすべてが機能しているようには見えず、どこに問題があるのか わかりません. 私はすでにstackoverflowで同様のケースを見てみましたが、私の問題に関連することは何もできませんでした.
これは、プログラムが実際にツリーを使用し始めるときに、明らかな理由で最終的にセグ フォールトにつながります。
gdb を実行してみましたが、なんらかの理由で行情報を見つけることができず、入力を求めるプロンプトが表示されるか、メモリ エラーまたは何かが発生するまですべてをスキップするため、行ごとに移動できません。そのため、ここでは gdb を実行してもあまり役に立ちません。これは、メイン関数がインクルード ファイルなどにあるためではないかと推測しています。しかし、それは論外です。
問題に関連するコードは次のとおりです。
struct treeStruct {
char *string;
struct treeStruct *left, *right;
};
typedef struct treeStruct *TreeType;
// Builds a tree
void treeBuilder(TreeType tree, char **phrase, long level){
// Gets the level (number of tabs) of the next phrase
long nextLevel = countTabs(*phrase + strlen(*phrase) + 1);
tree->string = *phrase + level; // Assigns the response pointer to the tree array
// Move the pointer to the next string, since the the strings need to be
// put into the tree in linear order
(*phrase) += strlen(*phrase) + 1;
if (level >= nextLevel){
// Compares the current level with the level of the next string
// to determine if returning up the tree is necessary;
// This should be the answer to a question.
tree->left = NULL;
tree->right = NULL;
return;
}
else{
// Makes sure the left and right pointers of the struct have
// allocated space
tree->left = calloc(1, sizeof(TreeType));
tree->right = calloc(1, sizeof(TreeType));
// Adds the yes and no branches to the tree, recursion will take care
// of adding sub-branches
treeBuilder(tree->left, phrase, level + 1);
treeBuilder(tree->right, phrase, level + 1);
}
return;
}
TreeType InitTree (char *file){
if(file == NULL){
printf("File '%s' does not exist.\n", file);
exit(2);
}
FILE *fp;
fp = fopen(file, "r");
// Create a space in memory for the loaded questions to occupy
static char *phrases;
phrases = (char *)malloc(MAXSTR * MAXNUMQS * sizeof(char));
copyText(fp, phrases);
fclose(fp);
// Create space in memory for the tree structure
TreeType tree;
tree = (TreeType) calloc(1, sizeof(TreeType));
// Create a pointer to a pointer so that treeBuilder can
// change what the first pointer is pointing to, so the strings in
// phrases can be added in order throughout the recursion
static char *phrase_ptr, **phrase_ptr2;
phrase_ptr = &phrases[0];
phrase_ptr2 = &phrase_ptr;
//Build the tree
treeBuilder(tree, phrase_ptr2, 0);
topNode = tree;
return tree;
}
これが tl;dr の場合は申し訳ありませんが、私の問題についてできるだけ明確にしたかったのです。