【问题标题】:Why the function malloc can be used like this?为什么函数 malloc 可以这样使用?
【发布时间】:2019-09-07 02:32:17
【问题描述】:

我正在阅读“专家 C 编程”一书,但这里的代码确实让我感到困惑。看不懂函数 malloc 的使用和这里返回的值,为什么运行这个会返回进程中分配的内存? 提前致谢。

#include<stdio.h>
#include<stdlib.h>
main()
{
    int MB = 0;
    while(malloc(1<<20))  ++MB;
    printf("Allocated %d MB total\n",MB);
}

【问题讨论】:

  • 运行直到malloc() 返回NULL,同时像筛子一样泄漏内存。目的可能是衡量一个程序可以分配多少内存,但取决于操作系统和 malloc 实现,这可能非常不准确,甚至是万能的无限循环。
  • 那本书写于 1994 年。从那以后发生了很多变化。试着找一本最近 10 年内写的书。
  • 它运行了三分钟,然后操作系统立即将其杀死,可能是因为它使用了“太多”内存。根据其他证据,它似乎已经实现了大约 64800000 MB 的虚拟地址大小(也就是说,它通过循环进行了 64800000 次,称为malloc 64800000 次),并且消耗了大约 40% 的机器内存。所以,是的,同意 user3386109 的观点,这个特定的实验可能不再那么有用了。
  • @steve: linux,对吧?搜索“乐观内存分配”。 “分配”的内存无关紧要,但 malloc 的内部数据结构和内核的页表是真实的。
  • 要么那个盒子要么他的盒子有 64T 的 RAM....:)

标签: c memory malloc


【解决方案1】:

&lt;&lt; 运算符执行按位左移。所以这会将二进制 1 向左移动 20 个位置。 即 0000 0000 0000 0000 0001 变为 1000 0000 0000 0000 0000。 这相当于 1 MB,因为一个 MB 被定义为 2^20。

因此,每个malloc() 调用都会尝试分配 1 MB。 malloc() 如果无法分配这么多空间,将返回 NULL。在 C 中,NULL 将评估为 False。

因此,在循环的每次迭代中,程序将分配 1 MB。如果成功,它会增加 MB 计数器。如果malloc() 空间不足,它将返回 NULL 并结束循环。然后printf 语句将打印分配的内存量。

【讨论】:

  • 但它可能会做其他事情。在我的机器上,它通过循环进行了超过 6400 万次行程,“成功”分配了 16 TB 内存(大约是机器物理内存的 4000 倍,磁盘空间的 64 倍),然后操作系统将它杀死为这样的内存猪。 (这是 MacOS,但 Linux 做了类似的事情。)
【解决方案2】:
unsigned int
A = 1 << 0, //1         byte        2^0     0x00000001  0b00000000000000000000000000000001
B = 1 << 8, //256       byte        2^8     0x00000100  0b00000000000000000000000100000000
C = 1 << 10,//1024      byte 1KB    2^10    0x00000400  0b00000000000000000000010000000000  
D = 1 << 20,//1048576   byte 1MB    2^20    0x00100000  0b00000000000100000000000000000000
E = 1 << 28;//256 e6    byte 1GB/4  2^28    0x10000000  0b00010000000000000000000000000000


const int TOP = 100;//25GB max
void* p[TOP] = {};
for (int i = 0; i < TOP; i++)           //32 bit system max 2Gb
{
    p[i] = malloc(0x10000000);          //1GB/4  or 256Mb
    //p[i] = malloc(1<<28);
    //p[i] = malloc(E);

    printf("%4d 0x%08x\n", i, p[i]);        //32 bit system
    //printf("%4d 0x%016llx\n", i, p[i]);   //64 bit system
}
for (int i = 0; i < TOP; i++)
    free(p[i]);

【讨论】:

    猜你喜欢
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 2020-04-12
    • 2021-12-22
    • 2013-12-19
    相关资源
    最近更新 更多