c-使用realloc填充内存



这个问题可能看起来有点琐碎,我正在尝试用C编写一个程序,在OOM被调用并杀死之前,它会尽可能多地消耗内存。尽管我最初将malloc()与memset()一起使用,但这次我决定尝试realloc(。我这么做纯粹是为了学习,因为我是C.的新手

我打算通过每次调用realloc()和memset()来分配1MB。当我运行这个程序来分配20MB:

1) 我不明白为什么输出中的一些地址是相同的(2-4)(5-10)&(11-20)?他们每个人不应该都不一样吗。

2) 我的程序真的消耗了20MB内存吗?我确实通过Valgrind运行了它,它说"1个块中的22020096个字节肯定在损失记录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,%dn",max_write,sleep_time);
}
ptr = (char *) calloc (1,size);
if (ptr == NULL) {
    perror("calloc Error:");
}
printf(" + Allocation: %pn",ptr);
do { 
    max++;
    size += (1048576);
    ptr = (char *) realloc (ptr,size);
    if (ptr == NULL) {
        perror("realloc Error:");
    }
    memset(ptr,0,size);
    printf(" + Pointer: %p / Memory: %dn",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

1) 我不明白为什么输出中的一些地址是相同的(2-4)(5-10)&(11-20)?他们每个人不应该都不一样吗。

正如其他人已经说过的,realloc不一定要移动现有的内存块,但可能只是扩展它

2) 我的程序真的消耗了20MB内存吗?我确实通过Valgrind运行了它,它说"1个块中的22020096个字节肯定在损失记录1中丢失"

这在某种程度上是特定于实现的,但您最终通常会要求比要求更多的内存。首先,free需要一些关于如何将内存与相邻的free块合并的元数据。这些信息通常位于alloc/realloc将返回的地址之前的几个字节中。此外,内存的组织方式可能不允许分配任意大小的内存,因此malloc只会返回最适合的内存。

正如realloc()的文档中所说,并在本SO答案中进一步解释,

该功能可以将存储块移动到新位置

这意味着,如果内存管理器可以在内存中的同一点分配请求的大小,那么它可以返回相同的指针。

对于(2),您的确切意思是"它真的分配20MB吗?"如果您向realloc()请求20MB,它会给您一个至少该大小的块,如果失败,则会给NULL。如果不这样做,它将完全违背函数的目的。

实际上,如果地址重复,看起来没问题。

它实际做的是:

  1. 好的,我有一个指针,它需要调整大小到X。这个指针后面还有多少内存?

  2. 它是Y。如果Y大于X,那么我真的不需要移动内存,我只需要将尚未使用的空间分配给我的指针。

  3. 如果Y低于X,那么它就不适合这里。可能还有另一个变量,它阻止我在适当的位置扩展指针。好的,让我们把它和所有的数据一起移到其他地方。请记住,我的指针需要指向连续内存区域。

我真的不明白你关于20mb的问题。你担心吗,这需要更多的时间?我不能说我知道原因,但试着进行另一次迭代,检查valgrind结果是否不同:也许这是一些运行时优化和预先分配更多空间的问题?但说实话,这只是一个盲目的猜测。

最新更新