2012-05-07 2 views
0

Что бы я ни делал, я не могу сказать, почему это утечка памяти. Я выпускаю всю динамически созданную память, но он говорит, что у меня 406 утечек. Любые подсказки были бы замечательными. Я потратил неделю, пытаясь понять это, и использовал crtdbg (не показывает никаких строк) и VLD и до сих пор не повезло. Извините за длинный код:Утечка памяти при использовании связанных списков и массивов хешей

---------- Block 742 at 0x00F06D50: 56 bytes ---------- 
Call Stack: 
c:\users\main\desktop\lab3123.c (113): lab3.exe!createNode + 0xA bytes 
c:\users\main\desktop\lab3123.c (152): lab3.exe!addToArr + 0x9 bytes 
c:\users\main\desktop\lab3123.c (66): lab3.exe!main + 0x10 bytes 
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (555): lab3.exe!__tmainCRTStartup + 0x19 bytes 
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): lab3.exe!mainCRTStartup 
0x76713677 (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes 
0x775B9F42 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes 
0x775B9F15 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes 
Data: 
74 65 63 68 6E 6F 6C 6F 67 79 00 CD CD CD CD CD  technolo gy...... 
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD  ........ ........ 
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD  ........ ........ 
CD CD CD CD 01 00 00 00         ........ ........ 


---------- Block 746 at 0x00F06E20: 56 bytes ---------- 
Call Stack: 
c:\users\main\desktop\lab3123.c (113): lab3.exe!createNode + 0xA bytes 
c:\users\main\desktop\lab3123.c (152): lab3.exe!addToArr + 0x9 bytes 
c:\users\main\desktop\lab3123.c (66): lab3.exe!main + 0x10 bytes 
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (555): lab3.exe!__tmainCRTStartup + 0x19 bytes 
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): lab3.exe!mainCRTStartup 
0x76713677 (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes 
0x775B9F42 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x63 bytes 
0x775B9F15 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x36 bytes 
Data: 
68 75 6D 61 6E 69 74 79 00 CD CD CD CD CD CD CD  humanity ........ 
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD  ........ ........ 
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD  ........ ........ 
CD CD CD CD 01 00 00 00         ........ ........ 


Visual Leak Detector detected 406 memory leaks (26480 bytes). 
Largest number used: 43684 bytes. 
Total allocations: 57944 bytes. 
Visual Leak Detector is now exiting. 
Press any key to continue . . . 
WORDNEW* createNode(char *str) 
{ 
    WORDNEW* w; 

    if(!(w = (WORDNEW*)malloc(sizeof(WORDNEW)))) 
     printf("Memory Allocation Error"), 
      exit(100); 
    strcpy(w->str, str); 
    w->count = 1; 
    return w; 
} 

//addToArr: adds a word to the hash array or linked list if there is a collision 
void addToArr(char *str, HASH_ARR_ELEM hashArr[]){ 
    int homeAddress = 0; 
    int addResult = 0; 
    int probe = 0; 
    HASH_ARR_ELEM *ph; 
    WORDNEW *w; 
    WORDNEW *rWord; 
    rWord = NULL; 
    homeAddress = hashFunct(str); 
    ph = &hashArr[homeAddress]; 

    if(ph->wordPtr == NULL){ 
     if(!(ph->wordPtr = (WORDNEW*)malloc(sizeof(WORDNEW)))) 
      printf("Memory Allocation Error"), 
       exit(100); 
     strcpy(ph->wordPtr->str, str); 
     ph->wordPtr->count = 1; 
    }else if(ph->wordPtr != NULL && ph->headPtr == NULL){ 
     if(!(strcmp(ph->wordPtr->str, str))) 
      ph->wordPtr->count++; 
     else { 
      ph->headPtr = createList(cmpWord); 
      w = createNode(str); 
      addNode(ph->headPtr,w,&probe); 
     } 
    }else { 
     w = createNode(str); 
     if(!(strcmp(ph->wordPtr->str, str))){ 
      ph->wordPtr->count++; 
      free(w); 
     }else if(retrieveNode(ph->headPtr,w,&rWord,&probe) == 1){ 
      rWord->count++; 
      free(w); 
     }else 
      addNode(ph->headPtr,w,&probe); 
    } //end else 


} // end addToArr 
+7

слышит отзыв. Получите вашу программу достаточно маленькой, чтобы у вас не было утечек памяти, вплоть до пустой основной, если нужно. Затем постепенно добавляйте обратно в материал, который, по вашему мнению, не должен течь. Соблюдайте причину утечки. –

+0

is (WORDNEW *) malloc (sizeof (WORDNEW)) когда-либо освобождался? –

+1

Еще один совет - разместить меньше кода. Я не знаю, сколько людей компилирует каждый кусок кода из вопросов SO, но я пытаюсь его пересмотреть. И более короткий код намного проще и быстрее просматривать. –

ответ

0

Из выше, я понял, вы считаете, что ошибка будет в addToArr. Вот несколько советов по поиску неисправности.

  • Удалить tempWord. Используется только поле str, а это копия параметра вызова str. Так что просто используйте str, где бы вы ни находились tempWord->str.

  • Затем, если у вас есть контроль над кодом для addNode, сделайте необходимое выделение там.

  • В противном случае заверните вызов addNode в функцию, которая выделяет структуру WORDNEW, копирует str в нее и устанавливает count в 1, а затем передает это в addNode.

Вы могли бы также:

  • переписать если-на-нибудь цепочку, факторизуя повторяющиеся разделы.
  • фактор из повторяющейся hashArr[homeAddress]. с помощью указателя ph->:

    HASH_ARR_ELEM * рН = & hashArr [homeAddress];

  • Включите предупреждения компилятора, чтобы предупредить вас о неоднозначных предложениях «else». В частности у вас есть:

    if (!strcmp...)){ 
         ... 
    }else 
    { 
        ... 
        if(addResult != 0) 
         if(addResult == -1){ 
          printf("Memory Overflow adding node\n"), 
          exit(120); 
         }else{ 
          etc... 
         } 
    

EDIT 2 (после рефакторинга addToArr)

Функция выглядит намного лучше, хотя все еще есть некоторые возможные точки улучшения и некоторые проверки ошибок исчезли. Но если у вас все еще есть утечка, то это не в addToArr. Что или кто говорит вам, что существует 406 утечек?

Улучшение теперь включает в себя:

  • (ph->wordPtr != NULL) ненужен, как вы знаете, ph->wordPtr == NULL из условия выше выше.

  • следующий бит является общим для обоих основных либо еще пунктов и может быть сделано только один раз:

    if (!strcmp(ph->wordPtr->str, str)) 
        ph->wordPtr->count++; 
    
  • использование PError на провал вместо Printf

  • добавить пробелы между параметрами вызова и вокруг else и if

  • удалить слепок возвращения таНос

  • удалить скобки и добавить пространства: if(!(strcmp(...))) становится if (!strcmp(...))

  • cmpWord не определен.

+0

Итак, вот что я сделал, исходя из вашего предложения, но все же. Ознакомьтесь с приведенным выше кодом (переиздано оригинальное сообщение) – TheMadKoder

+0

Уильям благодарит за подсказки. Я действительно ценю это. Визуальный детектор утечки - тот, который говорит мне, что у меня 406 утечек. – TheMadKoder

+0

Интересно, какой визуальный детектор утечки рассматривает утечку. Дает ли он какие-либо подсказки? Соответствует ли количество «утечек» каким-либо образом количеству записей в массиве хешей? –

Смежные вопросы