C - 检测到堆腐败

时间:2017-10-13 23:50:41

标签: c free heap-memory dynamic-arrays heap-corruption

我从教授那里获得了使用指针创建列表的意见。当我尝试释放内存时,我在所有函数中遇到free()问题。我不断收到一条消息:

  

“HEAP CORRUPTION DETECTED:正常块(#83)后0x00D58CE0。   CRT检测到应用程序在堆缓冲区结束后写入内存。“

我不知道如何修复它。我尝试了不同的东西但到目前为止没有任何效果。我不知道在哪里搜索它。我知道我的程序尚未正确保护,但它不会影响问题。在进一步研究它之前,我试图先消除它。另外,您对Visual Studio中的程序检测内存泄漏有什么建议吗?以下是我的功能,完整源代码如下所示:

Full Source Code

struct ListElement
{
    int value;
    struct element *next;
};

typedef struct ListElement List;
typedef List *ListEl;

void ViewListBackwards(ListEl *list_el)
{
    ListEl current_element = *list_el;
    int size = 0;
    int i = 0;
    int *reversed_array;
    while (current_element->next != NULL)
    {
        size++;
        current_element = current_element->next;
    }
    current_element = *list_el;
    reversed_array = (int*)malloc(size * sizeof(*reversed_array));
    for (i = size; i >= 0; i--)
    {
        reversed_array[i] = current_element->value;
        current_element = current_element->next;
    }
    for (i = 0; i <= size; i++)
    {
        printf(" %d. %d\n", i + 1, reversed_array[i]);
    }
    free(reversed_array);
}

void RemoveFromListFront(ListEl *list_el)
{
    if (ListEmpty(list_el) == 0)
    {
        ListEl current_element = *list_el;
        *list_el = current_element->next;
        free(current_element);
    }
    else
    {
        printf("List is empty!\n");
    }
}

void RemoveFromListBack(ListEl *list_el)
{
    if (ListEmpty(list_el) == 0)
    {
        ListEl current_element = *list_el;
        ListEl last_element = *list_el;
        while (current_element->next != NULL)
        {
            last_element = current_element;
            current_element = current_element->next;
        }
        last_element->next = NULL;
        free(current_element);
    }
}

1 个答案:

答案 0 :(得分:1)

在以下代码中:

   reversed_array = (int*)malloc(size * sizeof(*reversed_array));
for (i = size; i >= 0; i--)
{
    reversed_array[i] = current_element->value;
    current_element = current_element->next;
}
for (i = 0; i <= size; i++)
{
    printf(" %d. %d\n", i + 1, reversed_array[i]);
}

您正在分配(等于)int reversed_array[size]数组,但随后继续写入reversed_array[size]sizeof(int)超过分配的内存段的末尾。

您希望将for循环更改为:

for (i = size - 1; i >= 0; i--)

以便您编写的索引从reversed_array[size - 1]开始。

修改

顺便说一句,请注意,正如其他人在评论中建议的那样,不要投射malloc()。这在C中是不必要的,因为void *可以分配给任何对象指针类型变量,此外还可以隐藏代码中的错误,例如忘记包含stdlib.h

FWIW,您不需要sizeof(*reversed_array)周围的括号,因为只有在将sizeof运算符应用于类型时才需要括号。

这主要是一种风格建议;许多人(包括我自己)首选省略了无关的括号并将该表达式写为sizeof *reversed_array,因为这清楚表明sizeof一元运算符而不是一个功能。