【问题标题】:Why is std::bad_alloc thrown when enough memory is available?为什么当有足够的内存可用时会抛出 std::bad_alloc?
【发布时间】:2016-02-10 21:01:37
【问题描述】:

测试代码如下,用vs2013编译:

#include <memory>
#include <list>
#include <stdint.h>

int main()
{
    uint32_t one_size = 32 * 1024;
    uint64_t total_size = 0;
    auto deleter = [](char* p) { delete[] p; };
    using SharedBuffer = std::pair<std::shared_ptr<char>, int>;
    std::list<SharedBuffer> buffers;
    while (total_size < (uint32_t)2 * 1024 * 1024 * 1024)
    {
        std::shared_ptr<char> buffer;
        try
        {
            buffer = std::shared_ptr<char>(new char[one_size], deleter);
            total_size += one_size;
        }
        catch (const std::bad_alloc& e)
        {
            printf("%s\n", e.what());
            break;
        }
        try
        {
            buffers.emplace_back(std::make_pair(buffer, one_size));
        }
        catch (const std::bad_alloc& e)
        {
            printf("%s\n", e.what());
            break;
        }
    }
    return 0;
}

当进程的内存达到 2GB 时,它会捕获一个 bad_alloc 异常,但总共有 32GB 的 10GB 物理内存可用。

那么,为什么会导致呢?

【问题讨论】:

  • 你编译的是32位还是64位?
  • 32bit,就是这个原因。

标签: c++ memory-management bad-alloc


【解决方案1】:

32 位 Windows 程序将只有 2GB 的虚拟地址空间可用,除非设置了大地址感知标志,在这种情况下,它在 32 位主机上将有 3GB,在 64 位主机上将有完整的 4GB。即便如此,您也无法分配超过 3GB 的连续单个块。

如果您想超越该边界,您需要构建您的应用程序的 64 位版本。

【讨论】:

  • 在最坏的情况下,您可能还需要一个 64 位 cpu - 但希望没有人用 32 位封装卖给您那么多 RAM...!
  • @aho 我不记得最后一个不能运行 64 位的 CPU,那是很久以前的事了。但即使在今天,您也可以为您的 64 位处理器获得 32 位操作系统。
  • 即使启用大地址感知,也无法在单个块中分配 3GB。
  • @RaymondChen - 是的,当然,我会澄清说这只是虚拟地址空间。还有,天哪,它是Raymond Chen。 The Old New Thing 是一本好书!
猜你喜欢
  • 2012-01-16
  • 2012-06-16
  • 2016-04-04
  • 2017-05-26
  • 2011-02-03
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 2012-08-08
相关资源
最近更新 更多