我有一个大型数组,我用realloc()扩展它,并使用valgrind查看内存使用情况。
这是最小的例子:
#include <stdlib.h>
#include <stdio.h>
#define PASSES 1024 * 2
#define MEMTOALLOC 1024 * 1024
int main(void) {
void *remem = NULL;
void *newmem;
const unsigned int chunk = MEMTOALLOC / PASSES;
unsigned int i;
for(i = 0; i < PASSES; i++){
const unsigned int size = (i + 1) * chunk;
newmem = realloc(remem, size);
if (newmem == NULL){
printf("No memory!\n");
exit(1);
}
remem = newmem;
if (i % 1000 == 0)
printf("%10u processed\n", i);
}
free(remem);
}
如果PASSES为1,程序会立即重新分配所有内容并且valgrind报告:
total heap usage: 1 allocs, 1 frees, 1,048,576 bytes allocated
如果PASSES为100,则使用100个reallocs和valgrind报告逐步重新编程:
total heap usage: 100 allocs, 100 frees, 52,949,250 bytes allocated
如果我做了PASSES 1024,我会得到巨大的消费:
total heap usage: 1,024 allocs, 1,024 frees, 537,395,200 bytes allocated
这种内存使用的解释是什么?
答案 0 :(得分:1)
如果PASSES
为100,则您有chunk = 10485
。
您正在进行的分配是
i+1 size
1 10485
2 20970
3 31455
... ...
100 1048500
您可以添加所有这些尺寸,或者如果您知道1到100的总和是
100 * 101 / 2 = 5050
然后您可以轻松计算分配的总内存为
5050 * 10485 = 52,949,250
这正是valgrind的报道。这并不是说你在任何特定的时间分配了52MB。只有realloc
在程序生命周期内请求的总内存为52MB。
如果PASSES
为1024,则为chunk = 1024
,计算为
(1024 * 1025 / 2) * 1024 = 537,395,200
同样,在任何特定时间,您永远不会分配超过1MB,但realloc
请求的内存总量为537MB。