1

このコードは、BST を作成して埋め、リソースを解放しようとします。release() の 2 つのバージョンを以下に示します。

typedef struct Node {
    int d;
    struct Node *left;
    struct Node *right;
} Node;


int main() {

    Node **tree = NULL;

    tree = mkTree();
    if (!tree) {
        puts("problem\n");
        return 1;
    }

    insert(7, tree);
    insert(3, tree);
    insert(9, tree);
    insert(6, tree);

    printTree(*tree);
    release(tree);
    free(tree);

    return 0;

}
/* Make a new binary tree */
    Node **mkTree() {

    Node **t = malloc(sizeof **t);
    return t;
}

/* insert datum d into tree */


bool insert(int d, Node **tree) {

    Node *newptr = NULL;

    if (tree == NULL) { /*ptr to rootptr NULL */
        return false;
    }

    if (*tree == NULL) {
        newptr = buildNode(d);
        if (!newptr) {
            return false;
        }
        *tree = newptr;
        return true;
    }

    return insert(d, d < (*tree)->d ? &(*tree)->left : &(*tree)->right);
}

私が理解できないのは、以下の両方のケース (I と II) ですべてのリソースが解放されると valgrind が主張する理由です。release() を使用して各ノードをクリアしようとし、main の最後で free(tree) を呼び出して、main で宣言されている Node **tree をクリアします。

私。

/* release resources by passing Node **tree */

void release(Node **tree) {

    if (*tree) {
        Node *here = *tree;
        release(&here->left);
        release(&here->right);
    }
    free(*tree);

}

Ⅱ.

/* passing Node *tree. this shouldn't free anything, right? */

void release(Node *tree) {

    if (tree) {
        Node *here = tree;
        release(here->left);
        release(here->right);
    }
    free(tree);

}

選択にもかかわらず、4 つの挿入でこのプログラムを実行すると、

==5182== HEAP SUMMARY:
==5182==     in use at exit: 0 bytes in 0 blocks
==5182==   total heap usage: 5 allocs, 5 frees, 60 bytes allocated

ここで何が起こっているのですか?valgrind は malloc と free の数を集計しているだけですか?

4

1 に答える 1

2

の両方のバージョンがRelease同じことをしています。余分な (そして不必要な) レベルの間接化があるだけです。関数にポインターを渡し、そのポインターを解放できます。ポインターを保持する変数のアドレスを渡す必要はありません。

実際、 への呼び出しfreeはまさにそれを行います。ポインター値を受け入れるだけです (ポインターを保持している変数のアドレスではありません)。

于 2013-03-04T23:19:48.453 に答える