简体   繁体   中英

filling up memory using realloc

The question might seem little trivial,i'm trying to write a program in C,which just eats away memory as much as it could before OOM gets invoked and kills it.Although,i initially used malloc() with memset(),i decided to try realloc() this time.I'm doing this purely for learning purpose since i'm new to C.

I intend for an allocation of 1MB with every call to realloc() and memset().When i run this program to allocate 20MB:

1) I dont understand why in the output some of the address are the same (2-4) (5-10) & (11-20) ?Shouldn't each one of them be different.

2) Is my program really consuming 20MB of memory? I did run it through Valgrind and it says "22,020,096 bytes in 1 blocks are definitely lost in loss record 1 of 1"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <unistd.h>

int main (int argc,char **argv) {
char *ptr;
int max = 0;
int max_write;
int sleep_time;
size_t size = 1048576;
if (argc > 1) {
    sleep_time = (argv[2] ? atoi(argv[2]) : 2 ); 
    max_write  = (argv[1] ? atoi(argv[1]) : 1000);
    printf (" + To Write: %d,%d\n",max_write,sleep_time);
}
ptr = (char *) calloc (1,size);
if (ptr == NULL) {
    perror("calloc Error:");
}
printf(" + Allocation: %p\n",ptr);
do { 
    max++;
    size += (1048576);
    ptr = (char *) realloc (ptr,size);
    if (ptr == NULL) {
        perror("realloc Error:");
    }
    memset(ptr,0,size);
    printf(" + Pointer: %p / Memory: %d\n",ptr,max);
} while (max != max_write);
//
return(0);
}



OUTPUT:
./eatmemory 20 
+ Allocation: 0x7f2bb6b12010
+ Pointer: 0x7f2bb6451010 / Memory: 1
+ Pointer: 0x7f2bb6150010 / Memory: 2
+ Pointer: 0x7f2bb6150010 / Memory: 3
+ Pointer: 0x7f2bb6150010 / Memory: 4
+ Pointer: 0x7f2bb5b4f010 / Memory: 5
+ Pointer: 0x7f2bb5b4f010 / Memory: 6
+ Pointer: 0x7f2bb5b4f010 / Memory: 7
+ Pointer: 0x7f2bb5b4f010 / Memory: 8
+ Pointer: 0x7f2bb5b4f010 / Memory: 9
+ Pointer: 0x7f2bb5b4f010 / Memory: 10
+ Pointer: 0x7f2bb4f4e010 / Memory: 11
+ Pointer: 0x7f2bb4f4e010 / Memory: 12
+ Pointer: 0x7f2bb4f4e010 / Memory: 13
+ Pointer: 0x7f2bb4f4e010 / Memory: 14
+ Pointer: 0x7f2bb4f4e010 / Memory: 15
+ Pointer: 0x7f2bb4f4e010 / Memory: 16
+ Pointer: 0x7f2bb4f4e010 / Memory: 17
+ Pointer: 0x7f2bb4f4e010 / Memory: 18
+ Pointer: 0x7f2bb4f4e010 / Memory: 19
+ Pointer: 0x7f2bb4f4e010 / Memory: 20

As it says in the documentation for realloc() and explained further in this SO answer ,

The function may move the memory block to a new location

Which means that it could return the same pointer if the memory manager can allocate the requested size at the same point in memory.

For (2), what exactly do you mean "Is it really allocating 20MB?" If you ask realloc() for 20MB it will give you a block at least that size or NULL if it fails. If it didn't it would entirely defeat the purpose of the function.

1) I dont understand why in the output some of the address are the same (2-4) (5-10) & (11-20) ?Shouldn't each one of them be different.

As others already stated, realloc doesn't necessarily have to move the existing memory chunk, but may just extend it.

2) Is my program really consuming 20MB of memory? I did run it through Valgrind and it says "22,020,096 bytes in 1 blocks are definitely lost in loss record 1 of 1"

This is somewhat implementation specific, but you would usually end up claiming more memory than you asked for. For one, free needs some meta-data on how to merge the memory with neighboring free chunks. This information often resides in a couple of bytes right before the address that alloc/realloc will return. Also, the memory may not be organized in a way that would allow for allocations of arbitrary sizes, so malloc will just return the one that fits best.

Actually it looks ok if the addresses are repeating.

What it actually does is:

  1. Ok, I have a pointer, which needs to be resized to X. How much memory is left directly after this pointer?

  2. It is Y. If Y is greater than X then I don't really have to move my memory, I'll just assign the yet unused space to my pointer.

  3. If Y is lower than X, then it won't fit here. Probably there is another variable, that prevents me from expanding my pointer in place. Ok, let's move it somewhere else, along with all the data. Remember, that my pointer needs to point to a continuous region of memory.

I don't really get your question about 20mb. Are you worried, that it takes a bit more than that? Can't say I know the reason, but try with another iteration and check if the valgrind results vary: maybe it's a matter of some runtime optimisation and preallocation of more space in advance? But it's a blind guess, to be honest.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM