0

私が何をしても、なぜこれがメモリをリークしているのかわかりません。動的に作成されたすべてのメモリを解放していますが、406 リークがあると表示されます。どんなヒントも素晴らしいでしょう。私はそれを理解しようとして1週間費やしましたが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
4

1 に答える 1

0

上から、エラーがにあるとあなたが信じていることを私は集めますaddToArr。障害を見つけるためのいくつかの提案があります。

  • tempWordを削除します。フィールドのみが使用され、それは呼び出しパラメーターstrのコピーです。strだからstrあなたが持っているところならどこでも使うだけですtempWord->str

  • 次に、addNodeのコードを制御できる場合は、そこで必要な割り当てを行います。

  • それ以外の場合は、addNodeの呼び出しを、WORDNEW構造体を割り当て、strをその構造体にコピーし、countを1に設定してから、これをaddNodeに渡す関数でラップします。

あなたもそうかもしれません:

  • 繰り返されるセクションを除外して、if-the-elseチェーンを書き直します。
  • hashArr[homeAddress].ポインタを使用して繰り返されるものを除外しますph->

    HASH_ARR_ELEM * ph =&hashArr [homeAddress];

  • コンパイラの警告をオンにして、あいまいな「else」句について警告します。具体的には:

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

編集2(addToArrをリファクタリングした後)

改善の可能性のあるポイントがまだいくつかあり、いくつかのエラーチェックが消えましたが、関数は今でははるかに良く見えます。ただし、それでもリークがある場合は、addToArrにはありません。406のリークがあるとあなたに言っているのは何ですか?

改善点は次のとおりです。

  • 上記の条件から (ph->wordPtr != NULL)わかるように、これは不要です。ph->wordPtr == NULL

  • 次のビットは、両方のメインのelse句に共通であり、1回だけ実行できます。

    if (!strcmp(ph->wordPtr->str, str))
         ph->wordPtr->count++;
    
  • printfの代わりに失敗時にperrorを使用する

  • 呼び出しパラメータの間にスペースを追加しelseif

  • mallocリターンのキャストを削除します

  • if(!(strcmp(...))) 角かっこを削除してスペースを追加します。if (!strcmp(...))

  • cmpWordは未定義です。

于 2012-05-07T02:03:10.497 に答える