c++ - 内存块类在溢出后给出一个数字,为​​什么以及如何?

标签 c++ overflow

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

在经典的 MemoryBlock 类中,

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 更改为 1e101e11.

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 类型时,我将看不到这个警告,不知道为什么。

无论如何,我的问题是,141006540​​81215752192 是如何生成的?谢谢

最佳答案

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

使用 std::size_t 似乎是:

  • 将可表示范围增加到无符号 64 位(在您的特定平台上,因为它是 implementation defined),这样您的 100000000000 就不会溢出,并且行为将被定义...

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

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

如果你想保证一个特定的整数有特定的位数,你应该查看"Fixed width integer types" .


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

以后还可以用-fsanitize=undefined捕捉类似的签名溢出问题。

关于c++ - 内存块类在溢出后给出一个数字,为​​什么以及如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41486094/

相关文章:

c++ - 如何对 vector 进行二进制搜索以查找具有特定 id 的元素?

c++ - RValue 引用行为

jquery - 如何将同位素元素放在可滚动的 div 中并保留 jquery 悬停状态效果?

C++ 标准计时溢出

html - CSS表格有一行有溢出

c++ - CComPtr 内存泄漏

c++ - 没有数据成员的C++中的派生类问题

c++ - 代码中对象的大小

html - 溢出留下很多空白

c - C中堆栈溢出和无限次循环调用的区别