Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多次调用malloc-高于预期的内存使用率_C_Memory Management - Fatal编程技术网

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

多次调用malloc-高于预期的内存使用率,c,memory-management,C,Memory Management,当我在windows下运行以下32位应用程序(调试模式)时,内存使用量达到2GB限制,当我等于42885988时,循环中断: for(int i = 0; i < 104857600; ++i) { uint8_t* ptr = (uint8_t*)malloc(1); if (!ptr) { break; } *ptr = 0; } for(int i=0;i

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

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

    if (!ptr)
    {
        break;
    }

    *ptr = 0;   
}
for(int i=0;i<104857600;++i)
{
uint8_t*ptr=(uint8_t*)malloc(1);
如果(!ptr)
{
打破
}
*ptr=0;
}
104857600即100mb,那么如何解释上述程序的行为呢?

malloc(1)
不分配一个字节

malloc
手册页指出,返回的内存“对于任何内置类型都是适当对齐的”。因此,如果对
malloc
的第一次调用返回地址0x1000,第二次调用可能无法返回0x1001,因为该地址可能“对于任何内置类型都不是适当对齐的”(一些处理器无法访问奇数地址的字,或者通常无法访问不可被N整除的地址的N字节值,以及一些效率较低的地址的N字节值。)因此,第二个
malloc
调用必须返回至少0x1004或甚至0x1008

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

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


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

2GB/42885988是每个分配超过50字节的阴影


这比简单的Windows堆分配所期望的要多,因此我怀疑您正在运行调试版本,在这种情况下,分配的内存周围会有额外的保护字节开销。更多详细信息请参阅本文-。

跟踪内存块不是免费的。每个分配将使用多个字节。@Ry-你能详细解释一下吗?我不知道Windows的详细信息。看起来像是“低碎片堆”是一件事。但至少,你有8字节对齐。你知道分配一个字节的内存实际上毫无意义。@Ryker不要误解我,这个问题没关系。我只是想确保OP理解这一点。是的。我在调试模式下运行应用程序。