C中释放内存后的堆损坏
我有以下代码:C中释放内存后的堆损坏,c,visual-c++,heap-memory,C,Visual C++,Heap Memory,我有以下代码: #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
#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
}
#包括
#包括
#包括
#ifdef_WIN32
#包括
#elif定义的uu unix__
#包括
#恩迪夫
#定义工作台
#ifndef工作台
#定义N 10000
#恩迪夫
内部主(空)
{
#ifdef工作台
文件*output=fopen(“out.csv”,“w”);
对于(int N=10000;N问题最终位于循环的终止条件中对于(int j=i;j)循环条件j以多种N尺寸进行测试(10^3,10^4,10^5,10^6).对于上述循环条件,让我们做一个完整的练习,假设N=10000
和i=2
。然后N/i
将是5000
。使用j
的循环从2
到5000
。当j=2
然后i*j
是4
。当j=3
时,i*j
是6
。等等,直到j==N/i
(即j==5000
)。现在乘法i*j
将是10000
。这超出了10000
元素数组的范围(请记住,数组索引是从零开始的,因此N
元素数组的索引范围为0
到N-1
(包括))。值得注意的是,如果未定义BENCH,则不会释放
数组。我猜您确实超出了数组边界,而VS编译器只会在释放
上进行检查。因此,如果没有BENCH被污染,则仍然存在内存损坏,没有人注意到:)C没有任何类型的边界检查。一些独立的静态分析器程序可能能够检测到这个问题,但这是一个昂贵的操作,属于未定义行为的领域,因此编译器不必发出警告。