2016-06-17 2 views
6

私の質問を確認していただきありがとうございます。私はBSTを実装しているときに本当に基本的な問題に遭遇しました。つまり、「ポインタを割り当てるさまざまなアプローチの違いは何ですか?」ポインタを割り当てる方法の違いは何ですか?

int *p, q; 
p = &q; 

かを:我々は、すべてのポイントを使用することができます割り当てる知っ

int *p, *q; 
p = q; 

彼らは同じでなければなりません。しかし、下の私の場合、彼らは全く別の作業:

最初の方法を使用して
template <typename T> 
void Tree<T>::_insert(TreeNode<T>*& tree, const T& value, const unsigned& key) 
{ 
// TreeNode<T> node(value, key); 
// if(tree == nullptr) tree = &node; 
    TreeNode<T> *node = new TreeNode<T>(value, key); 
    if(tree == nullptr) tree = node; 

    else if(key < tree->index) _insert(tree->left, value, key); 
    else if(key > tree->index) _insert(tree->right, value, key); 
    else if(key == tree->index) std::cerr << "_insert: repeating key" << std::endl; 
} 

第二の方法は、正常に動作している間(1を指摘)、関数は、ノードと同じツリーを割り当てることはありません。

これは私の間違いですか、それとも自然に違うのですか?

答えて

3

最初の場合に注意してください:

// TreeNode<T> node(value, key); 
// if(tree == nullptr) tree = &node; 

nodeスタックに割り当てられたオブジェクトです。第二の場合に

TreeNode<T> *node = new TreeNode<T>(value, key); 
if(tree == nullptr) tree = node; 

nodeヒープに割り当てられているが

_insert関数が返されると、そのスタックフレームがポップされ、すべてのローカル変数/オブジェクトが無効になり、その結果、メモリエラーが発生するという違いがあります。

+0

ありがとう、本当にありがとうございます。だから私が正しく理解していると、エラーが出る理由は、ヒープで宣言された変数がスコープを超えたときに解放されるためです。したがって、最初のケースでは、「ノード」は解放され、ポインタ「ツリー」は"nullptr"、そうですか? –

+0

@XiangyuZhangいいえ、ヒープに割り当てられたメモリは、明示的にそうしなければ解放されません(そのため、2番目のケースで問題がなかったのです)。最初のケースでは、_insertのスタックフレームがポップされると、ポインタ "tree"は "nullptr"にリセットされません。それは元のままですが、_insert()が返されたので、 "tree" (以下の関数呼び出しのスタックフレームは割り当てられたスタックメモリを上書きします)、 "ツリー"ポインタの逆参照/アクセスは確かに問題になります。 –

+0

@XiangyuZhangたぶんhttps://en.wikipedia.org/wiki/Call_stack#STACK-FRAMEを見ると便利です –

3

なし、2つの方法が同じであってはならない。

    q
  • は、メモリ内の実際のオブジェクトであり、pがそれへのポインタ
  • 秒であるので、最初の割り当てp = &qは、完全に有効です割り当てp = qは、ユニット化されたポインタqpに割り当てます。これは未定義の動作です。

これは、2つの実装が異なる理由です。

qpに割り当てる場合は、qそのものを最初に割り当てる必要があります。たとえば、あなたはそれにnew intを割り当てることができます:

int *p, *q = new int; 
p = q; 

しかし、このケースではあなたにもpに直接new intを割り当てることができます。

0
int *p, q; 
p = &q; 

これは、pが整数qがメモリに格納されているアドレスを持つことを意味します。

int *p, *q; 
p = q; 

ここでは、ポインタqに格納されているアドレスをpにコピーしています。

関連する問題