2014-12-02 3 views
1

내 데이터 구조 강의에 대한 skewheap을 구현하려고합니다. algotihm이 작동하는지 여부를 무시하고 코드 자체에 문제가 있습니다. On VS 2012 코드는 실행되지만 예기치 않은 결과를 반환합니다. 디버깅하는 동안 전역 변수 (root)의 값이 예기치 않게 변경됩니다. Insert(1) 함수 (72 행)에 들어가기 전에 root의 값은 (key=5, right=NULL, left=NULL)이 될 것으로 예상됩니다. 그러나 Insert() 내부를 스 텝하면 root 값 필드가 임의로 변경됩니다. 다음에, 라인 (45)에 도달 :예기치 않은 전역 변수 값.

node *p = &input; 

root은 (input->key, null, null) 값을 변경한다. Dev C++에서는 프로그램이 SIGSEV으로 종료됩니다. 일반적인 sistuation은 비슷하지만, 에서 포인터는 leftright으로 예기치 않은 값으로 변경됩니다. 이것에 대한 이유는 무엇입니까? 이 체내 자동 변수로 선언되기 때문에

#include <iostream> 
#include <cstdio> 
#include <algorithm> 
using namespace std; 

struct node 
{ 
    int key; 
    node* right; 
    node* left; 
    node(int _key, node* _right, node* _left) 
    { 
     key = _key; 
     right = _right; 
     left = _left; 
    } 
}; 

node* root = NULL; 

node* Union(node* p1, node* p2) 
{ 
    node* p; 
    if (!p1) 
     return p2; 
    if (!p2) 
     return p1; 
    if (p1->key > p2->key) { 
     p = p1; 
     Union(p1->right, p2); 
    } else { 
     p = p2; 
     Union(p1, p2->right); 
    } 

    swap(p->left, p->right); 
    return p; 
} 


void Insert(int v) 
{ 
    node input = node(v, NULL, NULL); 
    node* p = &input; 
    root = Union(root, p); 
} 

void Print(node* v) 
{ 
    if (!v) { 
     return; 
    } 

    if (v->right) { 
     Print(v->right); 
    } 

    cout << v->key << endl; 

    if (v->left) { 
     Print(v->left); 
    } 
} 

int main() 
{ 
    Insert(5); 
    Insert(1); 
    cout << root->key; 

    system("pause"); 
    return 0; 
} 

답변

0

inputInsert()의 범위 지역이다. new으로 선언 된 객체와 같이 동적 저장 기간은 없습니다. Union() 메서드가 p2을 반환하면 (즉, input에서 노드를 반환하는 경우) rootInsert() 함수가 끝날 때 여전히 파괴되는 개체를 계속 가리 킵니다. 이것은 이라는 매달려 포인터이라고합니다.

가 발생하지 않도록하기 위해 동적으로 객체를 선언 :

node* input = new node(v, NULL, NULL); 
node* p = input; 
root = Union(root, p); 
+0

그 처리 걸렸다하지 않는 한 메모리가 누수되고 그래서, 노드 중 어느 것도이 프로그램에 해제되지 않은 것을 지적하고 싶습니다. 수동으로 삭제하지 않는 한 노드 주변에서 unique_ptr 또는 shared_ptr을 사용하는 것이 좋습니다. 누출 위험이 높으며 스마트 포인터의 작은 오버 헤드보다 중요 할 수 있습니다. –