2012-06-02 4 views
3
#include <iostream> 
#include <vector> 
#include <string> 
#include <algorithm> 
#include <unordered_map> 
#include <unordered_set> 
#include <cmath> 

using namespace std; 

template <class T> 
class binary_node { 
public: 
    T data; 
    binary_node<T> *left; 
    binary_node<T> *right; 

    binary_node(const T& data) 
     :data(data), left(NULL), right(NULL) { 
    } 
}; 

int main() { 
    binary_node<int>* node = new binary_node<int>(10); 
    node->left = new binary_node<int>(1); 
    node->right = new binary_node<int>(50); 

    binary_node<int>* ptr = node->left; 

    delete ptr; 
    ptr = NULL; 

    if (node->left == NULL) { 
     cout << "????"; 
    } 
    else { 
     cout << node->left->data << endl; 
    } 

    return 0; 
} 

나는 node->left == NULL을 기대하지만, node->left의 데이터가 가비지 임에도 불구하고 결과는 전혀 예상치 못한 결과입니다. Visual C++ 2010을 사용하고 있습니다. 아무도이 동작을 설명 할 수 있습니까?포인터 삭제 동작이 정상입니까?

~linkedlist() { 
#if DEBUG 
     cout << "~linkedlist() called.\n"; 
#endif 
     while (head != NULL) { 
#if DEBUG 
      cout << "delete node: " << head->data << '\n'; 
#endif 
      node<T>* temp = head; 
      head = head->next; 
      delete temp; 
      temp = NULL; 
     } 
    } 
+0

당신이'delete '를 호출 한 후에'ptr'은 실제로 아무 것도 가리 키지 않으므로'NULL'로 설정하면'node-> left'에 영향을 미치지 않습니다. – Cyclonecode

+1

'ptr '은'node-> left'에 저장된 포인터의 복사본 일 뿐이며'node-> left'는 변경되지 않습니다. 'binary_node * & ptr = node-> left;는 예상대로 작동합니다. – DCoder

+0

목록 순회가 다릅니다. 'head'를 다른 값으로 설정하고, 아마도 마지막 요소의'next' 노드가 다른 곳의 NULL로 설정되었을 것입니다. – juanchopanza

답변

9

수정할 수 없습니다. new binary_node<int>(50) 개체

그러나 다른 포인터를 통해 삭제하고 있습니다. 그런 다음 다른 포인터가 NULL이됩니다.

node-> left는 null로 설정되지 않습니다. 이와 같이 무엇이든 가리키는 내용 (할당 취소 된 메모리)은 무엇인지 가리 킵니다. enter image description here

+0

나는 아직도 그것을 얻지 않는다. 내가 링크드리스트 노드를 지울 때, 전체 목록을 가로 지르고 임시 포인터를 사용하여 현재 노드를 유지 한 다음'포인터를 가리키는 포인터 '또는'포인터에 대한 참조'를 사용하지 않고 삭제합니다. 그러면 잘 작동합니다. 이 둘은 어떻게 다른가요? 내 편집을 참조하십시오. – Chan

+0

@Chan : 기본 객체는 두 경우 모두 삭제됩니다. 그러나 링크 된 목록의 경우에는 'head'에 대한 포인터를 덮어 쓰므로 매달린 포인터가 없습니다. 이진 트리의 경우,'node-> left' 포인터 ** 값 **은 절대로 변경되지 않으므로 메모리가 할당 해제 된 후에도 노드의 메모리 위치를 계속 지적하게됩니다. – nhahtdh

+0

@nhahtdh : 고마워요.나는 당신의 요점을 본다. 그러나 나는 아직도 그 행동이 이상하다고 생각한다! 필자가 읽은 많은 데이터 구조 책은 포인터를 삭제하는 임시 기술을 사용하고 있으며 수년간 사용해 왔습니다. – Chan

1

당신은 NULLnode->leftNULL 대신 ptr에 설정해야합니다 : 횡단과 같은 노드에서 노드를 삭제하면

한편 EDIT
, 그냥 잘 작동합니다.

deleteNULL으로 전달되는 포인터를 설정합니다. 그것은 않아도 경우, 당신이 node->left 객체, 즉에 할당 된 데이터를 삭제하는 node->left

+1

Delete는 포인터를 'NULL'로 설정하지 않으므로 수동으로 수행해야합니다. – juanchopanza

+0

@ juanchopanza : 정보 주셔서 감사합니다. – nhahtdh

0

포인터가 실제로 단지 번호 :

binary_node<int>** ptr = &(node->left); 

delete *ptr; 
*ptr = NULL; 

또는이 여기

delete node->left; 
node->left = NULL; 

내가 무슨 말인지 보여주기 위해 만들어진 개선 묘사입니다 :

이 시도 . 메모리 내의 장소를 결정하는 수치. 메모리에 같은 위치를 가리키는 두 포인터가 있습니다 : ptrnode->left. 그런 다음 메모리를 삭제하고 포인터 중 하나를 NULL으로 다시 설정합니다. 물론 이 아니라이 아닌 다른 포인터도 재설정해야합니다.

관련 문제