【问题标题】:filling up memory using realloc使用 realloc 填充内存
【发布时间】:2014-10-19 19:33:52
【问题描述】:

这个问题可能看起来有点微不足道,我正在尝试用 C 编写一个程序,它只是在 OOM 被调用并杀死它之前尽可能多地消耗内存。虽然,我最初使用 malloc() 和 memset( ),这次我决定尝试 realloc()。我这样做纯粹是为了学习,因为我是 C 新手。

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

1) 我不明白为什么在输出中有些地址是相同的 (2-4) (5-10) & (11-20) ?难道不是每个地址都不同吗?

2) 我的程序真的消耗 20MB 内存吗?我确实通过 Valgrind 运行了它,它说“1 个块中的 22,020,096 个字节肯定丢失在 1 的丢失记录 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

【问题讨论】:

    标签: c malloc realloc


    【解决方案1】:

    1) 我不明白为什么输出中的某些地址是相同的 (2-4) (5-10) 和 (11-20) ?不应该每个都不同吗?

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

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

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

    【讨论】:

      【解决方案2】:

      正如documentation for realloc() 中所说并在this SO answer 中进一步解释,

      该函数可能会将内存块移动到新位置

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

      对于 (2),你到底是什么意思 “它真的分配了 20MB 吗?” 如果你向 realloc() 询问 20MB,它会给你一个至少那个大小的块或 NULL如果失败。如果不这样做,它将完全违背函数的目的。

      【讨论】:

      • 对不起,我的意思是我的程序在运行时真的消耗了 20MB 的内存。我并不是说要请求 realloc() 20MB。
      • 因为您实际上是使用memset() 写入所有内存,所以是的,您实际上是在“吃掉”20MB 的内存。
      • 谢谢,这是有道理的。我的最后一个问题是,这些地址真的来自堆吗?我认为它们看起来更像是从堆栈对我来说。无论如何我可以验证一个地址是否属于堆或堆栈帧?
      【解决方案3】:

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

      它的实际作用是:

      1. 好的,我有一个指针,需要将其大小调整为X。这个指针后面直接剩下多少内存?

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

      3. 如果 Y 小于 X,则不适合此处。可能还有另一个变量阻止我将指针展开到位。好的,让我们把它和所有数据一起移到其他地方。请记住,我的指针需要指向一个连续内存区域。

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

      【讨论】:

      • 感谢您的解释!
      猜你喜欢
      • 1970-01-01
      • 2015-06-18
      • 2019-06-20
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 2019-02-21
      • 2011-05-31
      相关资源
      最近更新 更多