Memoryblock class 溢出后给出一个数字,为​​什么以及如何?

Memoryblock class gives a number after overflow, why and how?

我的 mac 笔记本电脑有 4 GB 1600 MHz DDR3 内存。

在 classic MemoryBlock class,

class MemoryBlock
{
public:
    // Default constructor
    explicit MemoryBlock(): _length{0}, _data{nullptr} {}
    explicit MemoryBlock(const int l): _length{l}, _data{new int[l]} {}

    // Big-Five (blahblah)
    // --------

    int length() const
    {
        return _length;
    }

private:
    int _length;
    int* _data;
};

然后我试着看看像这样溢出后会发生什么,将 x1e9 更改为 1e10 再到 1e11

MemoryBlock x(100000000000);
Info<< "x's length = " << x.length() << endl;

这给了我(用 g++-6cmake 编译),

[LOG]   x(   1000000000)'s length = 1000000000
[LOG]   x(  10000000000)'s length = 1410065408
[LOG]   x( 100000000000)'s length = 1215752192

警告类似于

warning: overflow in implicit constant conversion [-Woverflow]
  MemoryBlock x(100000000000);

当使用size_t作为_length类型时,我将看不到这个警告,不知道为什么。

无论如何,我的问题是,14100654081215752192是如何生成的?谢谢

1215752192100000000000 % 2^32 的结果,其中 2^32 是 32 位整数 的最大表示 table 值(即大多数平台上 int 的大小)。请注意 signed overflow is undefined behavior!

使用 std::size_t 似乎是:

  • 将 representable 范围增加到无符号 64 位 (在您的特定平台上,因为它是 implementation defined,所以您的 100000000000 不会溢出,行为将被定义...

  • ...或将 representable 范围增加到无符号 32 位,其中 100000000000 溢出 (但以明确定义的方式) .

唯一可以确定先前声明的方法是验证 sizeof(int)sizeof(std::size_t) 在您的机器上的计算结果,并找出您的代码中发生的确切溢出。

如果您想保证特定整数具有特定数量的位数,您应该查看 "Fixed width integer types"


cppreference/Fundamental types 有一个很好的 table 包含 C++ 基本类型的最常见范围。

以后你也可以用-fsanitize=undefined来捕捉类似的签名溢出问题