2016-11-28 1 views
0

저는 C++로 학교 숙제를하고 있습니다 (아직 배우고 있습니다). 무작위로 생성 된 이진 트리 구조를 구현하려고하는데, shared_ptr을 사용하여 노드의 정보를 여러 위치에 저장합니다 (숙제가 필요함). (이것은 내 작은 테스트 프로그램입니다) 다음 예제 코드를 고려하십시오 :이 경우C++ : vector의 shared_ptr이 원래 shared_ptr을 업데이트하지 않습니다.

#include <vector> 
#include <memory> 


struct Node : public std::enable_shared_from_this<Node> { 
    char charValue; 
    int intValue; 
    std::shared_ptr<Node > left; 
    std::shared_ptr<Node > right; 
    std::shared_ptr<Node > parent; 

    std::shared_ptr<Node> getPtr() 
    { 
     return shared_from_this(); 
    } 

    Node() : intValue(0) 
    { 
     charValue = 0; 
    } 
}; 

int main(int argc, char**argv) { 

    std::vector<std::shared_ptr<Node>> treeQueue; 
    std::shared_ptr<Node> root = std::make_shared<Node>(); 

    treeQueue.clear(); 
    treeQueue.push_back(root->left); //std::shared_ptr<Node>(root->left)); //root->left->getPtr()); 
    treeQueue.push_back(root->right); //std::shared_ptr<Node>(root->right)); //root->right->getPtr()); 

    treeQueue[1] = std::make_shared<Node>(); //std::shared_ptr<Node>(new Node); 
    system("PAUSE"); 

    return 0; 
} 

, 내가 루트를 초기화하기, 그리고 내가 트리 구조를 선택할 때까지 빈 나무의 다른 모든 노드를 유지하려면 . 그리고 숙제에서, 나는 vector treeQueue에 푸시 한 후 어느 노드를 선택할지 결정합니다. (나는 무작위로 거기에서 그것을 선택한다).

문제 : 예를 들어 위의 코드에서 treeQueue [1]을 초기화하면 root-> right도 초기화 될 것으로 예상됩니다. 그것들은 같은 포인터이기 때문입니다. 그러나 그것은 비어 있습니다! 또한 treeQueue (또한 작동하지 않았다) 밀어 시도한 다른 방법을 넣어. 나는 "enable_shared_from_this"도 시도 했으므로 이것이 거기에있다.

이 방법이 있습니까? 아니면 내가 필요로하는 것과 동일한 기능을 제공 할 또 다른 기술이 있습니까?

원시 포인터를 사용하는 것이 좋지 않기 때문에 shared_ptr을 사용했지만이 문제가 발생한다는 것을 알았습니다. 나 좀 도와 줘, 내 마음을 잃을거야. 내가 할 수있는 곳을 수색했다. 나는 내가 찾은 모든 것을 시도했다.

+0

왜'root-> right'가 초기화 될 것으로 기대하십니까? 어디서나 초기화하지 않습니다. – lcs

+0

'treeQueue [1] = std :: make_shared ()'은'root-> right'에 영향을 미치지 않고 새로운 값으로 비어있는'shared_ptr' ('root-> right'의 복사본)을 지울뿐입니다. 'std :: vector *>'... – Jarod42

+0

나는 당신의 질문을 이해할 수 없다. 무엇을 성취하려고합니까? – Barry

답변

0

내 실수를 이해하게 해주신 Sam Varshavchik에게 감사드립니다. 그리고 Jarod42의 제안을 끝내고 treeQueue를

std::vector<std::shared_ptr<Node>*> 

과 같이 사용했습니다. 그래서 나는이 두 가지 주석에 대한 참고 자료로서이 주석을 해결책으로 표시하고 있습니다 :)

3

shared_ptrptr이 가리키고있는 것을 공유합니다. shared_ptr 자체는 모양, 사안 또는 형식에 상관없이 "공유"되지 않습니다. 동일한 객체 (공유 됨)를 참조하는 각 shared_ptr은 자체의 별도의 개별 공유 포인터입니다.

여기서 shared_ptr을 다른 shared_ptr으로 복사했습니다. 그런 다음 shared_ptr 복사본을 새로 생성 된 다른 것으로 대체했습니다 (shared_ptr).

새로 생성 된 shared_ptr은 원래 shared_ptr과 아무런 관련이 없습니다. 복사 된 첫 번째 파일은 참조하는 파일입니다.

코드는 다음과 동일하다 :

int *a=NULL; 

int *b=a; 

b=new int{4}; 

4을 반환하는 지금, 당신이 기대 *a합니까?. 당연히 아니지. 두 가지 완전히 다른 지침입니다.

+0

오, 이해합니다, 고마워요. 당신은 이것을 달성하기 위해 어떤 방법을 제안 할 수 있습니까? –

+1

'Node()'의 생성자에서 왼쪽/오른쪽으로 초기화해야합니다. 하지만 또 다른 문제가 생길 것입니다. : shared_ptr로 완전히 연결된 트리를 생성하는 경우 (생성자에서 또는 수동으로 제대로 수행되었는지 여부에 관계없이) 순환 참조 (parent와 children 사이에)가 만들어져 결과적으로 메모리 누출. 이제'shared_ptr'에 대해 모두 배웠으므로 약 포인터가 무엇인지 알아야합니다. –

관련 문제