是什么让使用 ifstream 时检测到堆栈粉碎?
What makes stack smashing detected when use ifstream?
今天我在使用 clang++
和 ifstream
时遇到异常错误:
*** stack smashing detected ***: <unknown> terminated
我的代码是这样的:
uint32_t Lod::getGraphicsOffset(std::ifstream *file, int graphicsNumber) {
uint32_t filesAmount = 0;
fileStream.seekg(76 + graphicsNumber*32);
fileStream.read(reinterpret_cast<char*>(&filesAmount), 16);
return filesAmount;
}
然而,当我只更改 fileAmount
代码中的位置时它是有效的:
uint32_t Lod::getGraphicsOffset(std::ifstream *file, int graphicsNumber) {
fileStream.seekg(76 + graphicsNumber*32);
uint32_t filesAmount = 0;
fileStream.read(reinterpret_cast<char*>(&filesAmount), 16);
return filesAmount;
}
有人知道为什么吗?是什么原因造成的?也许是一些UB?
在:
fileStream.read(reinterpret_cast<char*>(&filesAmount), 16);
将 16 个字节读入 4 个字节 filesAmount
,这会破坏堆栈并导致未定义的行为。
修复:
fileStream.read(reinterpret_cast<char*>(&filesAmount), sizeof filesAmount);
您可能应该检查 read
的 return 值以确保它成功:
if(!fileStream.read(reinterpret_cast<char*>(&filesAmount), sizeof filesAmount))
// Handle read failure.
这是未定义的行为。
fileStream.read(reinterpret_cast<char*>(&filesAmount), 16);
告诉fileStream
将16个字节的数据放入filesAmount
。 filesAmount
然而是一个 uint32_t
意味着它只有 4 个字节大(假设一个 8 位字节)。因此,您开始在 filesAmount
结束后写入数据,这是不允许的。简单的解决方法是将其更改为
fileStream.read(reinterpret_cast<char*>(&filesAmount), sizeof(filesAmount));
今天我在使用 clang++
和 ifstream
时遇到异常错误:
*** stack smashing detected ***: <unknown> terminated
我的代码是这样的:
uint32_t Lod::getGraphicsOffset(std::ifstream *file, int graphicsNumber) {
uint32_t filesAmount = 0;
fileStream.seekg(76 + graphicsNumber*32);
fileStream.read(reinterpret_cast<char*>(&filesAmount), 16);
return filesAmount;
}
然而,当我只更改 fileAmount
代码中的位置时它是有效的:
uint32_t Lod::getGraphicsOffset(std::ifstream *file, int graphicsNumber) {
fileStream.seekg(76 + graphicsNumber*32);
uint32_t filesAmount = 0;
fileStream.read(reinterpret_cast<char*>(&filesAmount), 16);
return filesAmount;
}
有人知道为什么吗?是什么原因造成的?也许是一些UB?
在:
fileStream.read(reinterpret_cast<char*>(&filesAmount), 16);
将 16 个字节读入 4 个字节 filesAmount
,这会破坏堆栈并导致未定义的行为。
修复:
fileStream.read(reinterpret_cast<char*>(&filesAmount), sizeof filesAmount);
您可能应该检查 read
的 return 值以确保它成功:
if(!fileStream.read(reinterpret_cast<char*>(&filesAmount), sizeof filesAmount))
// Handle read failure.
这是未定义的行为。
fileStream.read(reinterpret_cast<char*>(&filesAmount), 16);
告诉fileStream
将16个字节的数据放入filesAmount
。 filesAmount
然而是一个 uint32_t
意味着它只有 4 个字节大(假设一个 8 位字节)。因此,您开始在 filesAmount
结束后写入数据,这是不允许的。简单的解决方法是将其更改为
fileStream.read(reinterpret_cast<char*>(&filesAmount), sizeof(filesAmount));