【问题标题】:operator new with negative size具有负大小的新运算符
【发布时间】:2012-10-13 21:09:54
【问题描述】:

在 C++11 中,如果我们尝试使用全局运算符 new 分配负大小的数组,它将抛出 std::bad_array_new_length,但是 C++98 / C++03 呢?是 UB 还是会抛出 std::bad_alloc?

int main()
{
   int* ptr = new int[-1];
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    如果大小为 C++03 标准的负 5.3.4p6,则程序不正确:

    direct-new-declarator 中的每个常量表达式都应是一个整数常量表达式 (5.19),并计算为 严格的正值。 direct-new-declarator 中的表达式应为具有非负值的整数或枚举类型 (3.9.1)。

    以上引用涵盖new T[a][b];,其中b是根据语法的常量表达式a表达式(只有第一个维度)。

    【讨论】:

    • 我知道它在某个地方。 :)
    • 它说的是 noptr-new-declarator 中的常量表达式(这条规则也适用于 C++11),但是非常量表达式呢?
    • const size_t s = -1; int* ptr = new int[s]; s 是绝对正数吗?
    • @PiotrNycz 在 C 中,当然,我不是 100% 确定 C++,但我认为 size_t 也被指定为无符号类型。编辑:是的,是的。
    • @bames53:是的,我没有复制足够多的段落。第一句处理除第一个维度之外的所有维度(必须是严格的正常量表达式)。第二句话涵盖了第一个维度,它是一个(可能不是常量)表达式,只需要非负数。
    【解决方案2】:

    new[] 的定义表明它需要一个无符号整数,也类型定义为size_t。所以 应该 永远不会编译。

    见这里http://en.cppreference.com/w/cpp/types/size_t(这是一个无符号整数)。

    【讨论】:

      【解决方案3】:

      你可以通过int a[-1]得到这个:

      prog.cpp: In function ‘int main()’:
      prog.cpp:4: error: size of array ‘b’ is negative
      

      这对于int* a = new int[-1](运行时错误):

      terminate called after throwing an instance of 'std::bad_alloc'
        what():  std::bad_alloc
      

      【讨论】:

      • gcc 不会给你一个错误。对于其他编译器,您必须对数组大小使用非常量表达式
      • 不是我。是的,我知道输出。我询问了标准 qoutes。
      • -1 来自我。您似乎(最近)在 C++ 中很活跃,因此您应该知道(或快速学习)编译器什么关于该语言。 C++ 是由标准强制执行的,而不是由编译器生成的。
      • 该标准准确地说明了您在现已删除的答案中所反对的内容 - 大小必须是无符号类型。
      • 它编译是因为它是合法的。运算符 new 采用的 type 是无符号的;您传递给它的值不一定是。如果它是负数,则该值将转换为无符号类型,这通常是您不想要的。但是大多数时候会在运行时失败,因为转换的结果相当大,而且太大而无法成功分配。
      猜你喜欢
      • 2011-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-13
      • 2016-03-24
      • 1970-01-01
      相关资源
      最近更新 更多