释放C中的内存后堆损坏

我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#ifdef _WIN32
    #include <windows.h>
#elif defined __unix__
    #include <unistd.h>
#endif

#define BENCH

#ifndef BENCH
    #define N 10000
#endif

int main(void)
{
#ifdef BENCH
    FILE* output = fopen("out.csv","w");
    for (int N = 10000; N <= 100000; N += 10000)
#endif
    {
        int* a = malloc(N * sizeof(int));
        if (a == NULL)
            abort();

        for (int i = 2; i < N; i++)
            a[i] = 1;

#ifdef BENCH
        clock_t begin = clock();
#endif

        for (int i = 2; i < N; i++)
        {
            if (a[i])
            {
               #if defined (BENCH) && defined (_WIN32)
                    Sleep(1);
               #elif defined (BENCH) && defined (__unix__)
                    sleep(0.001);
               #endif
               for (int j = i; j <= N / i; j++)
                    a[i * j] = 0;
            }

        }

#ifdef BENCH
        clock_t end = clock();
        double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
        fprintf(output,"%d,%f\n",N,time_spent);
        free(a); //This is where the corruption occurs
#else
        for (int i = 2; i < N; i++)
        {
            if (a[i])
                printf("%9d ",i);
        }
        puts("");
#endif
    }
#ifdef BENCH
    fclose(output);
#endif
}

如果未定义BENCH,程序将使用预定义的N并将结果显示在控制台上。该算法的性能尚未得到评估。

如果定义了BENCH,则使用(N)循环创建具有不同输入大小for的多个问题实例。一旦出现问题,该算法的性能就会记录在output.csv文件中。然后,必须释放为该实例的数组分配的内存。

至少根据microsoft Visual C ++编译器在Visual Studio 2019上所说的,这就是堆损坏发生的地方。有人知道为什么会这样吗? malloc()free()在我看来都是正确的。如果删除free(),程序运行正常。

xiaomaxiaofeng 回答:释放C中的内存后堆损坏

问题最终位于循环for (int j = i; j <= N / i; j++)的终止条件中,而不是free()中。将其更改为for (int j = i; j < N / i; j++)可解决堆损坏问题。

正如一些程序员哥们在评论中指出的那样,在调试器没有通知我的情况下,发生了“超出界限”异常。在Visual Studio中,我主要编写C#代码,因此我有一种幻想:如果出现问题,我至少会在发生不良情况的那一行中收到异常。

不是不是,因为C没有任何类型的边界检查。在某些情况下,未定义的行为趋向于“精细”运行,然后当一切崩溃时,一些无关紧要的事情就会改变。正如 AbbysSoul 所指出的,即使未定义BENCH,在所有情况下都发生堆损坏。当在损坏的堆上调用诸如free()之类的关键操作时,该过程注定要崩溃。

这里的主要教训是检查C程序中的所有代码行,特别是当您在发生异常的行中没有看到任何错误时,尤其是。

本文链接:https://www.f2er.com/3133101.html

大家都在问