0

I have a large array and I expand it with realloc() and use valgrind to see memory usage.

here is minimal example:

#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);
}

If PASSES is 1, program realloc everything at once and valgrind reports:

total heap usage: 1 allocs, 1 frees, 1,048,576 bytes allocated

If PASSES is 100, program realloc gradually with 100 reallocs and valgrind reports:

total heap usage: 100 allocs, 100 frees, 52,949,250 bytes allocated

and if I do PASSES 1024, I get huge consumption:

total heap usage: 1,024 allocs, 1,024 frees, 537,395,200 bytes allocated

What is the explanation of this memory usage?

Nick
  • 9,962
  • 4
  • 42
  • 80
  • You don't have any code. You don't have any questions. What do you expect to see in response to your post? – R Sahu Dec 30 '14 at 23:33
  • Code not really needed, but I will edit my question. – Nick Dec 30 '14 at 23:35
  • 2
    This is a case where you can probably solve your own problem simply by attempting to create an **[MCVE](http://stackoverflow.com/help/mcve)**. – user3386109 Dec 31 '14 at 00:25
  • If memory buffer is being relocated (i.e. pointer returned by realloc isn't the same it got as parameter), then it makes perfect sense. – keltar Dec 31 '14 at 06:14
  • @keltar - what exactly makes sence? sure pointer is not the same, this is why i assign it to the v->buffer. Old pointer is not valid anymore, i do not need to free it. – Nick Dec 31 '14 at 08:34
  • I am editing the question and posting MCVE now. – Nick Dec 31 '14 at 10:12

1 Answers1

1

In the case where PASSES is 100, you have chunk = 10485.
The allocations you are doing are

 i+1      size
  1      10485
  2      20970
  3      31455
 ...      ...
 100   1048500

You can add up all of those sizes, or if you know that the sum of 1 to 100 is

100 * 101 / 2 = 5050 

then you can easily calculate the total memory allocated as

5050 * 10485 = 52,949,250 

which is exactly what valgrind is reported. That's not to say that you have 52MB allocated at any particular time. Only the that the total memory requested from realloc over the lifetime of the program was 52MB.

If PASSES is 1024, then chunk = 1024, and the calculation is

(1024 * 1025 / 2) * 1024 = 537,395,200

Again, you never have more than 1MB allocated at any particular time, but the total amount of memory requested from realloc was 537MB.

user3386109
  • 34,287
  • 7
  • 49
  • 68