为什么内存分配2 ^ 80字节不会失败?

时间:2012-09-20 06:59:06

标签: c++ memory-management

以下代码不会抛出异常并打印“成功”。为什么?

#include <iostream>

int main() 
{
    size_t size = size_t(1024)*1024*1024*1024*1024*1024*1024*1024;
    char* data = new char[size];

    if (data == NULL)
        std::cout << "fail" << std::endl;
    else
        std::cout << "success" << std::endl;

    return 0;
}
  • 编译器:g ++(Ubuntu / Linaro 4.6.3-1ubuntu5)4.6.3
  • OS:Ubuntu 12.04
  • RAM:8 GB

如果这是它的工作方式,我该如何检查我是否有足够的内存?

[编辑:让我的愚蠢代码更正确一点,现在如果删除两个*1024则至少会失败x64

5 个答案:

答案 0 :(得分:20)

我的编译器可以回答这个问题:

$ g++ --version
g++ (GCC) 4.7.1 20120721 (prerelease)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -Wall -Wextra -pedantic q12507456.c++
q12507456.c++: In function 'int main()':
q12507456.c++:5:42: warning: integer overflow in expression [-Woverflow]
$

答案 1 :(得分:6)

这很可能是因为您请求的数字太大而无法存储在整数中,并且您在此处遇到溢出,并且分配的内存实际上远远低于您的预期。< / p>

这里2 ^ 80 = 1208925819614629174706176根据http://en.wikipedia.org/wiki/Yobibyte

答案 2 :(得分:5)

1024*1024*1024*1024*1024*1024*1024*1024

在计算时导致整数溢出 - 也就是说,它将取模2 ^ 32(或2 ^ 64,取决于您的系统),并且这是可以分配的零字节。

答案 3 :(得分:4)

请注意,在Linux上malloc(最终支持new)可以overcommit

  

自2.1.27起,有一个sysctl VM_OVERCOMMIT_MEMORY和proc文件   / proc / sys / vm / overcommit_memory,值为1:do overcommit,和0   (默认):不要。

malloc将成功并保留VA,但不会以页面备份。访问页面时,可能会也可能不会成功提交页面。 OOM Killer可能会运行。如果全部失败,您将获得访问GPF。

对于这种行为是否疯狂(理智的人是在这个阵营中)还是出色的(疯狂的人都在那个阵营),意见分歧。

答案 4 :(得分:1)

也许你知道以下内容,但我只是为了澄清而说明。不会抛出异常,代码正在由if语句测试。无论您使用哪种术语和方法进行测试,都需要注意更相关的观察。    您的系统保存整数的最大值,C ++将在编译期间通过检查并相应地采取某种方式来考虑它。再一次,你可能也已经知道了。   我的猜测是,该值要么回到0,那么要达到过量,要么指针开始指向它之前的值保持不变(最有可能)。在这种情况下,指针不会是NULL。尝试在声明时将其设为NULL,然后分配内存并查看天气与否通过你的if语句。