C语言 使用链表和哈希数组时内存泄漏



无论我做什么,我都不知道为什么这是泄漏内存。我正在释放所有动态创建的内存,但它说我有 406 个泄漏。任何提示都会很棒。我花了一周的时间试图弄清楚并使用了crtdbg(不显示任何线条(和VLD,但仍然没有运气。对不起,代码太长了:

---------- Block 742 at 0x00F06D50: 56 bytes ----------
Call Stack:
c:usersmaindesktoplab3123.c (113): lab3.exe!createNode + 0xA bytes
c:usersmaindesktoplab3123.c (152): lab3.exe!addToArr + 0x9 bytes
c:usersmaindesktoplab3123.c (66): lab3.exe!main + 0x10 bytes
f:ddvctoolscrt_bldself_x86crtsrccrtexe.c (555): lab3.exe!__tmainCRTStartup + 0x19 bytes
f:ddvctoolscrt_bldself_x86crtsrccrtexe.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:usersmaindesktoplab3123.c (113): lab3.exe!createNode + 0xA bytes
c:usersmaindesktoplab3123.c (152): lab3.exe!addToArr + 0x9 bytes
c:usersmaindesktoplab3123.c (66): lab3.exe!main + 0x10 bytes
f:ddvctoolscrt_bldself_x86crtsrccrtexe.c (555): lab3.exe!__tmainCRTStartup + 0x19 bytes
f:ddvctoolscrt_bldself_x86crtsrccrtexe.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

从上面,我认为错误在addToArr. 以下是查找故障的一些建议。

  • 删除临时字。仅使用 str 字段,该字段是 str 调用参数的副本。 因此,只需在有tempWord->str的地方使用str即可。

  • 然后,如果您可以控制 addNode 的代码,请在其中进行必要的分配。

  • 否则,将对addNode的调用包装在一个函数中,该函数分配一个WORDNEW结构,将str复制到其中并将count设置为1,然后将其传递给addNode。

您可能还:

  • 通过分解重复的部分来重写 if-the-else 链。
  • 使用指针ph->分解重复hashArr[homeAddress].

    HASH_ARR_ELEM *ph = &hashArr[homeAddress];

  • 打开编译器警告以警告您不明确的"else"子句。具体来说,您有:

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

编辑 2(重构 addToArr 后(

该功能现在看起来好多了,尽管仍有一些可能的改进点并且一些错误检查已经消失。但是,如果您仍然有泄漏,那么它不在 addToArr 中。什么或谁告诉您有 406 泄漏?

改进现在包括:

  • (ph->wordPtr != NULL)是不必要的,因为您从上述条件中ph->wordPtr == NULL知道。

  • 以下位对于两个主 else 子句都是通用的,只能执行一次:

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

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

  • 移除马洛克回归的演员表

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

  • cmpWord 是未定义的。

相关内容

  • 没有找到相关文章

最新更新