【发布时间】:2016-02-11 20:08:24
【问题描述】:
我的程序以一种非常令人费解的方式出现段错误。它发生在 std::string 库代码中,所以我假设我的程序正在其他地方覆盖 std::string 代码。当我尝试将 char* 分配给 automatic 变量中的 std:string 时,会发生段错误:
struct MyStruct
{
std::string name;
int winch_ndx;
...
};
void MyFunction(const char * nodeName)
{
MyStruct dataL;
dataL.name = nodeName; <-- segfault
...
}
由于 dataL 是一个自动变量,代码的其他部分无法覆盖它占用的内存,所以我猜库代码本身正在被值 0x6C2FD8 覆盖(见下文)。令人费解的是,Valgrind 根本没有检测到原始的无效写入。我不知道如何将这个 0x6C2FD8 引入到 std::string 代码中。任何见解将不胜感激。
Valgrid 输出和我的 valgrind 命令如下。
==17112== 进程以信号 11 (SIGSEGV) 的默认操作终止
==17112== 地址 0x6C2FD8
的映射区域权限错误==17112== 在 0x9B07D87:__exchange_and_add (atomicity.h:47)
==17112== by 0x9B07D87:__exchange_and_add_dispatch (atomicity.h:80)
==17112== by 0x9B07D87: std::string::_Rep::_M_dispose(std::allocator const&) [clone .part.12] (basic_string.h:246)
==17112== by 0x9B07F78: _M_dispose (char_traits.h:243)
==17112== by 0x9B07F78: std::string::_M_mutate(unsigned long, unsigned long, unsigned long) (basic_string.tcc:487)
==17112== by 0x9B083ED: std::string::_M_replace_safe(unsigned long, unsigned long, char const*, unsigned long) (basic_string.tcc:684)
==17112== by 0x613ADA: MyFunction (comm.cpp:1108)
valgrind --gen-suppressions=all --error-markers=BEGIN_MARK,END_MARK --free-fill=FF --malloc-fill=FF --trace-malloc=yes --trace-children=yes --track-origins=yes --read-var-info=yes --partial-loads-ok=no --log-file=vg2.out my_program
【问题讨论】:
-
试试这个:
if(nodeName) { dataL.name = std::string(nodeName); } -
如果您尝试以其他方式访问
nodeName,您可能会遇到相同的段错误。你为什么还要使用 valgrind? -
您是否在编译时将警告视为错误?我怀疑堆栈损坏(警告将帮助您找到堆栈损坏,valgrind 也应该这样做......但是嗯)
-
使用您的代码,会发生相同的段错误。 nodeName 不是 NULL 并且包含一个有效的以 null 结尾的字符串。我使用 Valgrind 是因为崩溃的症状表明我正在写入超出程序某些未知部分的内存。至于警告,你的意思是用-Wall编译吗?