2

私はC++言語を学んでいて、BSTを書き込もうとしていますが、問題が発生しています。空のツリーに要素を追加しようとすると、ルートはNULLになりますが、要素を追加した後も、追加が成功したにもかかわらず、ルートはまだNULLです(デバッグモードで見たので、ノードはtmpとして設定されています)。なぜそれが起こるのか分かりません。

struct Node
{
    int data;
    Node* left;
    Node* right;
};

struct Tree
{
    Node* root;
};

Tree createTree()
{
    Tree tmp;
    tmp.root = NULL;
    return tmp;
}

void addToNode(Node* node, int value)
{
    Node* tmp = new Node;
    tmp->data = value;
    tmp->left = NULL;
    tmp->right = NULL;
    if(node == NULL)
        node = tmp;
    else if(value >= node->data)
        addToNode(node->right, value);
    else
        addToNode(node->left, value);
}

void add(Tree* tree, int value)
{
    addToNode(tree->root, value);
}

int _tmain(int argc, _TCHAR* argv[])
{
    Tree tree = createTree();
    add(&tree, 10);
    printf("%d", tree.root->data);
    scanf("%*s");
    return 0;
}
4

3 に答える 3

3

addToNodeに割り当てる関数では、はローカル変数であるためnode、その割り当ては関数呼び出しに表示されません。addToNodenode

代わりに、参照として渡す必要があります。

void addToNode(Node*& node, int value)
{
    ...
}
于 2012-11-08T11:58:27.957 に答える
3

ポインターを関数に渡すときは、ローカルバージョンのポインターを作成します。このローカル変数(node)は、実際に、渡した外部ポインタと同じメモリを指します。ただし、この変数(それが指すメモリではなく、ポインタ変数自体)を変更しようとすると、ローカル変数のみが変更されます

したがって、nodeはと同じメモリ位置を指しますtreeが、node変数自体は変数と等しくないtreeため、変更は外部関数からは見えません。

複雑に聞こえますが、申し訳ありませんが、これとまったく同じです。

void foo( int a )
{
    a++;
}
int main()
{
    int var = 5;
    foo( var );
    std::cout << var;
}

もちろん、この場合は変更されvarませんa。関数内で変更されているのはです。

この問題を修正するには、ポインター自体ではなく、ポインターへの参照を渡します。

void addToNode(Node*& node, int value)
于 2012-11-08T12:04:14.207 に答える
1

Joachimはすでに答えに私を打ち負かしましたが、とにかくこの観察を追加します。

コードがメモリリークします。

void addToNode(Node* node, int value)
{
    Node* tmp = new Node;
    tmp->data = value;
    tmp->left = NULL;
    tmp->right = NULL;
    if(node == NULL)
        node = tmp;
    else if(value >= node->data)
        addToNode(node->right, value);
    else
        addToNode(node->left, value);
}

を呼び出すたびに、で新しいインスタンスがaddToNode作成されますが、パラメータがそうでない場合、この新しいインスタンスは削除されず、アプリケーションの他の部分からアクセスできなくなります。NodetmpNode* nodeNULLNode

これを回避する方法はいくつかあります。最も簡単なのは、新しいインスタンスを作成する前にnodeあるかどうかを確認することです。NULL

于 2012-11-08T12:04:00.613 に答える