1

修正済み: 問題はポインタではなく再帰にありました。各再帰を介して戻ると、返された VAR が古いメインツリーにリセットされます。グローバル VAR を作成し、それを return の前に設定してから、関数全体を void に戻すことで修正しました。メモリリークはありません。

main() のポインタ変数に malloc されたポインタ アドレスを渡そうとしています。

コードはある程度まで機能します。FinalTree から main にポインタ アドレスを渡す代わりに、FinalTree() で malloc されたメモリを free() できないことを意味する新しいコピーを作成します。メモリ チェックを行うと、解放されていないメモリが残ります。

これまでのコードは次のとおりです。

Tree* FinalTree(Forest** forest, int FinalFreq)
{

    Tree* maintree = mktree(); //this function calls malloc and have to use it
    Tree* tree1 = pick(*forest);
    Tree* tree2 = pick(*forest);

    maintree->frequency = tree1->frequency + tree2->frequency;
    maintree->left = tree1;
    maintree->right = tree2;

    //Make sure forest isnt barren
    if (maintree->frequency != FinalFreq)
    {
        plant(*forest, maintree);
        FinalTree(forest, FinalFreq);
    }

    return maintree;
}

これは、次の方法で main() から呼び出されます。

Tree* tfinal = FinalTree(&finit, header.checksum);

ポインターは私を夢中にさせています..何が欠けていますか?

4

1 に答える 1

0

あなたの質問を完全に理解していない場合はご容赦ください。ただし、コメントに基づいて、あなたが今何を指しているのかがわかると思います。

この関数はツリーを作成しますが、最上位のルート ノードのアドレスのみを返します。あなたの問題は、その場合free()、ツリーの残りの部分がまだ割り当てられていることです。正しいですか? もしそうなら、これに対する解決策はFreeTree(Tree *)、ツリーをトラバースしfree()、個々のリーフノードを元に戻す専用の関数を作成することだと思います。

次のようなもの(テストされていません):

void FreeTree(Tree *tree) {
  if (tree == NULL)
    return;

  FreeTree(tree->left);
  FreeTree(tree->right);
  free(tree);                                                                                                            
}

更新:ああ、わかりました。それは確かに奇妙です。maintree関数には、mktree()それを作成する側を変更するものは何もありません。plantポインタへの参照を取らない限り:

void plant(Forest forest, Tree *&tree)

次にplant()、ポインターのmaintree指す先を変更できます。それ以外の場合は、ルート ノードを返す必要があるように見えます。

于 2013-02-14T06:48:24.847 に答える