2013-10-30 2 views
0

이진 트리 데이터 구조를 사용하는 프로그램을 작성하고 있습니다. 모든 노드를 자유롭게하는 루틴을 작성할 때 설명 할 수없는 특이한 문제를 발견했습니다.이진 트리 구현으로 메모리 프리 함수 난수 인쇄

이 루틴은 다음과 같습니다

void destroy_tree(NodeT **tree){ 

    if(*tree != NULL){ 
     destroy_tree(&(*tree)->left); 
      free((*tree)->left); 
     destroy_tree(&(*tree)->right); 
      free((*tree)->right); 
    } 
    return; 
} 

기본적으로 2 성급 포인터는 함수에 전달됩니다. 포인터를 해제하기 전에 각 노드가 NULL인지 확인합니다. NodeT은 NodeT 구조에 대한 왼쪽 및 오른쪽 포인터를 포함하는 구조입니다. 이것들은 내가 풀려고하는 포인터들이다.

구조는 다음과 같이 정의됩니다 : 당신이 기대하는 것처럼) 자유없이

typedef struct{ 
    int val; 
    struct tnode *right, *left; 
}NodeT; 

(호출 아무 반응이 없습니다. 무료 통화가 주석 때 그러나, 결과는 다음과 같다 :

enter image description here

나는 숫자 블록이 변경됩니다 프로그램을 실행하지만 그들은 항상 결국 충돌로 반복되는 각각의 시간을.

이 함수의 원래 통화는 당신이 기대하는 것입니다,

destroy_tree(&rootNode); 

는 rootNode를은 여기서 NodeT *rootNode;

아이디어가 있으십니까?

+0

왜 이중 포인터로 작성해야합니까? 이것은 단일 포인터로 더 간단합니다. –

+0

그 출력은 어디서 오는가? 누가 그것을 인쇄하고 있습니까? –

+0

나는 동의한다 - 그러나 이것은 프로젝트이고 우리는 2 성급 포인터를 구현하도록 요청 받았다. 훨씬 더 간단합니다. – sherrellbc

답변

3

시도 대신 현재 노드 확보하기 :

void destroy_tree(NodeT **tree){ 

    if(*tree != NULL){ 
     destroy_tree(&(*tree)->left); 
     destroy_tree(&(*tree)->right); 
     free(*tree); 
    } 
    return; 
} 
+0

나는 이것을 시험 할 것이다. – sherrellbc

+0

위대한 작품. 나는 이것을 훨씬 더 어렵게 만들고 있었다. 두 자식 노드를 모두 해제 한 다음 호출자에게 반환하면 이전 현재 노드가 될 부모 자식 노드를 해제합니다. 제안 해 주셔서 감사합니다. – sherrellbc

1

당신은 당신이 실행중인 시스템의 어떤 종류의 말을하지 않습니다,하지만 나는 인쇄가 힙에 대해 불평 힙 진단 루틴에서 오는 추측 것 부패.

그래서 문제는 아마도 나무가 실제로 나무가 아니라는 것입니다. NodeT은 트리에 두 번 나타납니다 (DAG이므로). 또는 더 나쁜 경우 부모 중 하나가 포인터를 가리 킵니다. 그 중 하나는 힙 손상 (정의되지 않은 동작)으로 이어져 어떤 것도 발생할 수 있습니다.

valgrind 또는 일부 다른 힙 디버깅 도구를 사용하여 문제를 줄이는 것이 좋습니다. 그래도 실제 문제가있는 곳 (즉, 트리를 만드는 코드의 어딘가에 있음)은 알려주지 않습니다.

+0

트리의 각 노드는 NodeT 구조체입니다. 나는 나무를 나무로 지키기 위해 매우주의를 기울 였지만 항상 가능성이있다. 제안 된 소프트웨어를 제공해 주셔서 감사합니다. – sherrellbc