2012-07-14 3 views
1

다음은 내 Node 클래스입니다. 내가 실행하면값을 기준으로 포인터를 전달하는 바이너리 트리에 재귀 적으로 삽입 하시겠습니까?

int main() 
{ 
    Btree<int> tree; 

    tree.insert(5, tree.root); 

    cout << tree.root->data << endl; 

    tree.insert(6, tree.root); 

    cout << tree.root->right->data << endl; 

} 

, 나는 독방 감금 오류를 얻을 :

public: 
    Node<T>* root; 
    Btree() : root(NULL){} 
    void insert(T data, Node<T>* parent) 
    { 
     if(!parent ) 
     { 
     parent = new Node<T>(data); 
     return; 
     } 
     else if(data < parent->data) 
     { 
     insert(data, parent->left); 
     } 
     else if(data > parent->data) 
     { 
     insert(data, parent->right); 
     } 
    } 

}; 

여기 내 주요 기능입니다 :

class Node 
{ 
private: 
public: 
    T data; 
    Node<T>* left; 
    Node<T>* right; 
    Node(T dat) : data(dat), left(NULL), right(NULL) 
    {} 
}; 

여기 내 BTREE 클래스에 정의 된 내 삽입 기능입니다.

포인터 변수 부모가 값에 의해 전달되므로 부모가 가리키는 새 노드를 만들 때 삽입 기능을 종료하면 잃어 버릴 수 있다고 생각합니까? 여기에 이중 포인터를 사용해야한다는 의미입니까?

누군가가 메모리에서 진행되고있는 일에 대해 철저히 설명하여 계획대로 작동하지 않게 할 수 있습니까? 내 진단이 올바른지 아니면 다른 문제가 있습니까?

삽입 할 두 번째 매개 변수로 tree.root를 전달할 때 Node *를 전달할 예정입니다. 이제 값으로 전달 되더라도 호출하는 주 기능에서 전달한 주소와 같지 않습니다. 그래서 부모 (내가 main, tree.root에서 전달한 주소) = new Node라고 할 때 부모 노드의 주소 인 tree.root의 주소에 힙에 새로운 노드를 만들지 말아야합니까? 왜 가치 전달은 이것을 퍼지로합니까?

+0

오히려 추측보다, 당신은 실행할 수 있지만, 좀 더 간결한 해결책이 디버거에서 프로그램을 실행하면 어떤 라인에서 seg-fault가 발생했는지 정확히 ** 알려줍니다. 그런 다음 변수 값 등을 검사하여 어떤 일이 발생했는지 파악할 수 있습니다. –

+0

어떤 행이 seg 오류를 일으켰는지 알고 있습니다. 값으로 주소를 전달하는 것에 대한 설명을 요구하고 있습니다. – ordinary

답변

2

이 경우 값으로 전달할 때의 문제는 함수 내부의 형식 인수에 대한 모든 할당이 호출자에게 표시되지 않는다는 것입니다. 따라서,이 과제

if(!parent ) 
{ 
    parent = new Node<T>(data); // <<== HERE 
    return; 
} 

호출자의 tree.root에 영향을주지 :

tree.insert(5, tree.root); 

함수의 parent 포인터의 값을 변경 한 후 즉시 폐기된다; 나무의 rootNULL으로 남습니다.

이 문제에 대한 수정 프로그램은 다음과 같이 포인터에 대한 포인터를 전달하는 것입니다 : parent가 전달 된 포인터의 사본이되도록

void insert(T data, Node<T>** parent) { 
    if(!*parent ) 
    { 
     *parent = new Node<T>(data); 
     return; 
    } 
    else if(data < (*parent)->data) 
    { 
     insert(data, &((*parent)->left)); 
    } 
    else if(data > (*parent)->data) 
    { 
     insert(data, &((*parent)->right)); 
    } 
} 
2

C++는 값으로 전달합니다. 그러므로 그것에 할당하는 것은 지속적인 효과가 없습니다. 이 문제를 해결하는 가장 쉬운 방법은 메소드의 서명을 변경하여 포인터에 대한 참조를 허용하는 것입니다. 이렇게하면 프로그램의 나머지 부분을 변경하지 않고 자동으로 컴파일러가 원래 포인터로 업데이트됩니다.

1

dasblinkenlight가 가장 잘 답변했습니다.

가 (포인터를 참조라고도 함) 포인터의 참조를 가져옵니다 :

void insert(T data, Node<T>*& parent) 
    { 
     if(!parent ) 
     { 
     parent = new Node<T>(data); 
     return; 
     } 
     else if(data < parent->data) 
     { 
     insert(data, parent->left); 
     } 
     else if(data > parent->data) 
     { 
     insert(data, parent->right); 
     } 
    } 

여기에 대한 자세한 내용보기 : 는 http://www.codeproject.com/Articles/4894/Pointer-to-Pointer-and-Reference-to-Pointer

관련 문제