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;
};
然后我试着看看像这样溢出后会发生什么,将 x
从 1e9
更改为 1e10
再到 1e11
。
MemoryBlock x(100000000000);
Info<< "x's length = " << x.length() << endl;
这给了我(用 g++-6
和 cmake
编译),
[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
类型时,我将看不到这个警告,不知道为什么。
无论如何,我的问题是,1410065408
和1215752192
是如何生成的?谢谢
1215752192
是 100000000000 % 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
来捕捉类似的签名溢出问题
我的 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;
};
然后我试着看看像这样溢出后会发生什么,将 x
从 1e9
更改为 1e10
再到 1e11
。
MemoryBlock x(100000000000);
Info<< "x's length = " << x.length() << endl;
这给了我(用 g++-6
和 cmake
编译),
[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
类型时,我将看不到这个警告,不知道为什么。
无论如何,我的问题是,1410065408
和1215752192
是如何生成的?谢谢
1215752192
是 100000000000 % 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
来捕捉类似的签名溢出问题