使用calloc分配连续内存分配失败

问题描述 投票:0回答:1

我在 64 位系统中运行附加代码,因此我期望对于这个缓冲区字节(21B),我能够分配内存,但 calloc 无法做到这一点,因此它返回一个 NULL 指针。对于较小的缓冲区字节(如 20 B),它会很好,但在 21 B 时会中断,并且当我检查不同的机器时,这个断点可能会有所不同。我只需要知道我应该在该系统中检查什么,它会阻止我进行内存分配?

#include <unistd.h>
#include <cstdio>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
int main(int argc, char* const argv[]) 
{
   size_t bufferBytes = 21000000000;
  //  size_t bufferBytes = 20000000000;
  // Use words instead of bytes to ensure 8-byte alignment.
    size_t bufferWords = bufferBytes / 8;
    auto m_buffer      = reinterpret_cast<char *>(calloc(bufferWords, 8));
    if(m_buffer==NULL)
    {
        std::cout<<"Not a valid pointer"<<std::endl; 
    }
}
c++ dynamic-memory-allocation calloc
1个回答
0
投票

“我可以使用

malloc
分配多少内存”这一经典问题取决于多种因素,例如您的操作系统、
malloc
/
calloc
的库实现以及您拥有多少 RAM。

但是,一般来说,对于如此巨大的分配,库实现完全绕过堆并直接进入操作系统服务(Linux 上为

mmap
,Windows 上为
VirtualAlloc
)。由操作系统决定对这些分配施加什么限制。例如,我的机器单个
calloc
的最高容量为 52GB(具有 16GB 物理 RAM)。

64 位系统的虚拟地址空间(目前)非常大。然而,对于物理地址空间来说情况并非如此,大多数消费者计算机都具有 8-32GB RAM。

当您需要如此大的分配时,您的操作系统实际上并没有为您保留任何物理内存,而只是将虚拟地址空间中的某个区域标记为可用。当您实际尝试访问该内存时,操作系统实际上会为您分配它。您可以通过在任务管理器(或 Linux 上的

htop
)中检查进程来查看这一点。在程序的最后添加一个
while(1);
,你会发现你的程序几乎不使用任何内存。

一旦您开始使用比实际 RAM 多的内存,操作系统就会开始将其交换到磁盘(使您的计算机运行速度非常慢),以便在 RAM 中腾出空间。然而,它只能在一定程度上做到这一点。它无法使用硬盘驱动器上的数百 GB 空间进行交换。因此,操作系统将达到一定的大小(请参阅 Linux 上的setrlimit),这样它就不会向您保证它可能无法提供的内存。

© www.soinside.com 2019 - 2024. All rights reserved.