2014-04-14 3 views
0

Valgrind를 사용했으며 코드가 insert() 및 buildName() 함수에서 메모리 누수 위치를 확인할 수 없습니다. Valgrind는 이러한 기능이 있다고 말하지만 정확한 위치를 정확히 알 수는 없습니다. 나는 코드로 메모리를 새기라는 개념에 대해 아주 새로운 것이다. 누구 한테 도움을 줘? 건배! 빈c - 이진 검색 트리 삽입으로 메모리 누수

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 


/* Node of tree */ 
typedef struct Node { 
    int order; 
    char value; 
    struct Node * left; 
    struct Node * right; 
} Node; 

Node * insert(Node * node, char value, int order){ 
    if(node == NULL){ 
     /* free(node); */ 
     node = (Node *)malloc(sizeof(Node)); 
     node->value = value; 
     node->order = order; 
     node->left = NULL; 
     node->right = NULL; 
     return node; 
    } 
    if(order > node->order){ 
     node->right = insert(node->right, value, order); 
    } 
    else if(order < node->order){ 
     node->left = insert(node->left, value, order); 
    } 
    return node; 
} 

char * buildName(const char * old, const char * newpart) { 
    char * dot; 
    char * buf = NULL; 

    dot = strrchr(old, '.'); 
    if (dot) { 
     size_t len; 
     len = snprintf(NULL, 0, "%.*s%s.%s", 
        (int)(dot - old) + 1, old, newpart, dot + 1); 
     buf = malloc(len + 1); 
     if (buf) { 
     snprintf(buf, len + 1, "%.*s%s.%s", 
       (int)(dot - old) + 1, old, newpart, dot + 1); 
     } 
    } 
    return buf; 
} 

void decode(Node * root, Node * origRoot, char * bitString, char * filename) { 
    FILE * fp; 
    int i = 0; 

    fp = fopen(filename, "w"); 

    if (fp) { 
     while(bitString[i] != '2'){ 
      if(bitString[i] == '0'){ 
       if(root->left == NULL && root->right == NULL) { 
        root = origRoot; 
        i--; 
       } 
       else root = root->left;    
      } 
      else if(bitString[i] == '1'){  
       if(root->right == NULL && root->left == NULL) { 
        root = origRoot; 
        i--; 
       } 
       else root = root->right;      
      } 
      if(root->value != -1){ 
       fputc(root->value, fp); 
       printf("%c", root->value); 
      } 
      i++; 
     } 
    } 
    fclose(fp); 
} 

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

    FILE * fp; 
    Node * root = NULL; 
    char bitString[256]; 
    char * filename; 
    int numNodes; 
    int value; 
    int order; 
    int i = 0; 
    char c; 

    if (argc < 2 || argc > 2) { 
     printf("No file specified or too many arguments. Exiting...\n"); 
     exit(1); 
    } 

    fp = fopen(argv[1], "r"); 

    if(!fp){ 
     printf("Cound not open command file: %s", argv[1]); 
     return 0; 
    } 

    if(fp){ 
     fscanf(fp, "%d", &numNodes); 

     while(i < numNodes){ 
      fscanf(fp, "%d", &value); 
      fscanf(fp, "%d", &order); 
      root = insert(root, value, order); 
      i++; 
     } 

     i = 0; 
     while((c = fgetc(fp)) != EOF){ 
      bitString[i] = c; 
      i++; 
     } 
    } 

    fclose(fp); 

    filename = buildName(argv[1], "decoded"); 

    decode(root, root, bitString, filename); 

    return 0; 
} 

추가 :

void empty(Node * node) { 
    node = NULL; 
    if(node != NULL){ 
    Node * left = node->left; 
    Node * right = node->right; 
    free(node); 
    if (left) 
     empty(left); 
    if (right) 
     empty(right); 
    } 
} 
+0

valgrind 보고서에 대한 pastebin 링크를 포함 할 수 있습니까? 디버그 기호로 프로그램을 컴파일 한 경우 valgrind는 누수 된 메모리가 할당 된 행 번호를 제공해야합니다. – tkocmathla

+0

프로그램 끝에 할당 된 메모리가 해제되지 않았습니다. 그 의미에서? – BLUEPIXY

+0

"Leaking"은 프로그램을 종료하기 전에 런타임 동안 malloc() 된 메모리를 삭제하기 위해 free()를 호출하지 않는 것을 의미합니다. 트리를 걷고 malloc() 함수를 사용하여 메모리를 비우는 destroy_tree() 함수가 없으므로 malloc()을 insert()에 호출하여 할당 된 모든 메모리가 유출되었습니다. 마찬가지로 buildName에서는 malloc()을 사용하고 사용 후에 free()하지 않는 버퍼를 반환하므로 main()이 종료 될 때 메모리가 유출됩니다. – JohnH

답변

0

은 당신이 함수에서, "다른 사람을"누락 생각합니다. 새로운 노드를 만들 때 즉시 반환하지 않으면 다음 if로 진행합니다. 이로 인해 바이너리 검색 트리가 올바르게 구성되지 않을 수도 있습니다. 이것을 시도하십시오 :

Node * insert(Node * node, char value, int order){ 
if(node == NULL){ 
    /* free(node); */ 
    node = (Node *)malloc(sizeof(Node)); 
    node->value = value; 
    node->order = order; 
    node->left = NULL; 
    node->right = NULL; 
    return node; 
} 
else if(order > node->order){ 
    node->right = insert(node->right, value, order); 
} 
else if(order < node->order){ 
    node->left = insert(node->left, value, order); 
} 
return node; 
} 
+0

그러나 첫 번째 'if'블록의 끝에는 'return node;'가 있습니다. 이것은 스타일의 문제이지만, 이제는 첫 번째'if' 블록의 끝에'return node; '를 생략 할 수 있습니다. 그럼에도 불구하고이 변화는 아무 것도하지 않습니다. – ThoAppelsin

+0

@ThoAppelsin 당신 말이 맞습니다. 나는 그 반환을 간과했다. 그런 다음 메모리 누출을 일으킬 수있는 다른 것을 보지 못합니다. 문자열도 동적으로 할당되며 프로그램 종료시 할당이 취소됩니다. 따라서,이 코드에서 메모리 모양이 발생할 수있는 위치를 알 수는 없습니다. – armanali

+0

프로그램이 끝나면 운영 체제가 정리되지만 _code 자체는 할당을 취소하지 않습니다. 이것이 valgrind가 불평하는 이유입니다. 운영 체제가 프로그램의 최종 정리를 처리하기 전에 누수가 있는지 찾습니다 (그렇지 않으면 분석 할 필요가 없습니다). – JohnH