valgrind报告奇怪的内存使用情况

时间:2014-12-30 23:29:24

标签: c valgrind realloc

我有一个大型数组,我用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

这种内存使用的解释是什么?

1 个答案:

答案 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。