声明硬编码的 std::string 会导致缓冲区溢出

Posted

技术标签:

【中文标题】声明硬编码的 std::string 会导致缓冲区溢出【英文标题】:Declaring hardcoded std::string causes buffer overflow 【发布时间】:2012-02-13 21:23:53 【问题描述】:

我的程序中有以下行导致运行时警告:

if (!is_directory("C:\\NGFMS_Debug\\Files") && !create_directories("C:\\NGFMS_Debug\\Files"))

警告文本如下:“XXX.exe 中发生缓冲区溢出,已损坏程序的内部状态。”

警告来自对“is_directory(...)”的调用。我猜字符串的空间没有被分配,但我认为这样的语法是合法的。

is_directory 函数是 boost/filesystem.hpp 的一部分,我正在使用以下命名空间:

using namespace boost;
using namespace boost::filesystem;
using namespace std;

这是在 VS2005 C++ 下编译的。有什么想法吗?

更新

我尝试了几种不同的方法并逐步执行了代码,这就是我发现的。

如果我这样做

char* path_chars_c;
path_chars_c = "C:\\Debug\\Files";
string path_str_c(path_chars_c);

变量path_chars_c 包含适当的字符串,但变量path_str_c 包含初始化后的垃圾。所以看起来字符串初始化在这里被破坏了。有人见过这个吗?

【问题讨论】:

缓冲区溢出不会导致异常——如果您确实看到异常,那么您需要提供更多信息。 @ildjarn 我想我看到了一个 Windows 断点。帖子相应更改。 我很困惑。这是编译器警告吗?您应该逐字发布消息。 这是一个运行时警告,显示“XXX.exe 中发生缓冲区溢出,已损坏程序的内部状态。” @Ian:你需要通过调试器运行你的程序。 【参考方案1】:

这是一个令人惊讶的错误——这似乎是 boost::filesystem::is_directory() 的一个非常标准的用法。您是否尝试过使用调试器进入它以查看问题发生在哪里?

想到一个(远程)可能性——如果您将启用 NDEBUG 的库与禁用 NDEBUG 的库链接,您可能会遇到麻烦。特别是,一些 boost 数据类型会在调试打开时分配一些额外的调试字段。因此,如果一个对象由一段认为调试已关闭的代码创建,但随后被另一段认为调试已打开的代码使用,那么您可能会出现随机内存错误(例如缓冲区溢出)。

【讨论】:

哇,这是一个非常好的猜测。确保一切都在调试模式下编译修复它。

以上是关于声明硬编码的 std::string 会导致缓冲区溢出的主要内容,如果未能解决你的问题,请参考以下文章

std::string,std::vector,std::accumulate注意事项

使用 std::string 作为通用 uint8_t 缓冲区

open() 的缓冲参数和迭代文件时使用的硬编码预读缓冲区大小有啥区别?

如何知道std :: string是否正确编码?

为啥创建静态 const std::string 会导致异常?

为啥创建静态 const std::string 会导致异常?