代码之家  ›  专栏  ›  技术社区  ›  MykC

在C/C++中使用MALOC和FLASH并获得错误堆损坏检测

  •  2
  • MykC  · 技术社区  · 14 年前

    自由(位置)运行时我遇到问题。

    void printTree(nodeT node, int hieght)
    {
        int *position;
        position = (int*)malloc(hieght * sizeof(int*));
        for (int i = 0; i <= hieght; i++)
        {
            position[i] = 0;
        }
        BOOLEAN DONE = FALSE;
        while (DONE == FALSE)
        {
            printMoveDown(&node, position);
            printLEAFNode(&node, position);
            DONE = printMoveUp(&node, position);
            printSingleKey(&node, position);
        } 
        free(position);
        position = NULL;
    }
    

    我从VS2010得到的完整错误消息是检测到堆损坏:在正常块(64)之后,在0x00031390处。CRT检测到应用程序在堆结束后写入内存。

    调试程序说问题发生在:dbgheap.c中

    extern "C" void __cdecl _free_dbg_nolock
    line 1376:  if (!CheckBytes(pbData(pHead) + pHead->nDataSize, _bNoMansLandFill, nNoMansLandSize))
                    if (pHead->szFileName) {..}
                    else { this is where the program stops }
    

    我试着用更少的东西来设置相同的情况,看看是否可以缩小问题的范围。

    void function (int y)
    {
        int *x;
        x = (int*)malloc(y * sizeof(int*));
        free(x);
        x = NULL;
    }
    

    这与上面没有for循环和while循环的情况相同。这是可行的。移除for循环才是它工作的原因。我不知道为什么。我查了一下CRT是什么,但它对我来说都是相当新的概念,我想我可以在不了解这些CRT的情况下解决这个问题。

    for循环将值分配给分配给位置的内存,除此之外,我想不出这会导致问题的原因……实际上,现在我想起来了。我把回路改为高度+1,解决了这个问题。

    2 回复  |  直到 10 年前
        1
  •  3
  •   Matthew Flaschen    14 年前

    应该是:

    position = malloc(hieght * sizeof(int));
    

    或:

    position = malloc(hieght * sizeof *position);
    

    这是你所拥有的未定义的行为。你可能只是走运了,因为 int int* 尺寸相同。

    编写循环的典型正确方法是:

    for (int i = 0; i < hieght; i++)
    {
        position[i] = 0;
    }
    

    您也可以在这里使用calloc:

    position = calloc(hieght, sizeof *position);
    

    内存将为您归零,因此您不必循环。

    另外,如果这真的是C,那么演员表就多余了。

        2
  •  0
  •   Richard C    10 年前

    我认为循环中的问题是<=实际上应该是<。 因此循环循环循环一次太多,会损坏堆中的下一项!