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
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 子句都是通用的,并且可以只执行一次:

    if (!strcmp(ph->wordPtr->str, str))
         ph->wordPtr->count++;
    
  • 在失败时使用 perror 而不是 printf

  • 在调用参数之间和周围添加空格elseif

  • 删除 malloc return 的演员表

  • 删除括号并添加空格:if(!(strcmp(...))) 变为if (!strcmp(...))

  • cmpWord 未定义。

于 2012-05-07T02:03:10.497 回答