多次调用 malloc - 高于预期的内存使用量

Irb*_*bis 2 c memory-management

当我在 Windows 下运行以下 32 位应用程序(调试模式)时,内存使用量达到 2GB 限制并且当 i 等于42885988时循环中断:

for(int i = 0; i < 104857600; ++i)
{
    uint8_t* ptr = (uint8_t*)malloc(1);

    if (!ptr)
    {
        break;
    }

    *ptr = 0;   
}
Run Code Online (Sandbox Code Playgroud)

104857600 那是 100mb 那么如何解释上述程序的行为?

Wil*_*urn 8

malloc(1) 不分配一个字节。

malloc手册页注意到,记忆又回到“为适应任何内置型排列。” 因此,如果第一次调用malloc返回地址 0x1000,第二次调用可能无法返回 0x1001,因为该地址可能“不适合任何内置类型对齐”。(某些处理器无法访问奇数地址处的字,或者通常无法被 N 整除的地址处的 N 字节值,而其中一些处理器的效率较低。)因此第二次malloc调用必须至少返回 0x1004 或甚至 0x1008。

此外,malloc必须分配额外的内存来存储有关它返回给您的缓冲区的信息。例如,当您稍后调用 时free,该函数必须知道缓冲区的大小。在至少还有 8 个字节的 64 位机器上。根据运行时管理堆的方式,它可能必须存储其他信息。

如果您假设每个malloc实际上分配至少 8 个字节(用于对齐)加上另外 8 个或 16 个用于内务处理,您可以看到 1 亿次调用malloc1 个字节每个可以让您超过 2GB。

我不确定您的每个调用是否实际使用了 16 或 24 个字节或其他任何内容;关键是它远不止一个。