我在以下行之后遇到了段错误:
this->my_set.insert(my_string);
该集已初始化并包含std :: string。 插入字符串不是指一个dandling指针,它是以null结尾的。 集合中包含的所有其他字符串都不为null,并以'\ 0'结尾。
这是回溯:
#0 0xb7076bdb in std::_Rb_tree_insert_and_rebalance () from /usr/lib/libstdc++.so.6
#1 0xb7480795 in std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_insert_ (
this=0x97bf918, __x=0x0, __p=0x980aa78, __v=@0xaabfc1c4) at /usr/include/c++/4.3/bits/stl_tree.h:854<br/>
#2 0xb7480b96 in std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_insert_unique (this=0x97bf918, __v=@0xaabfc1c4) at /usr/include/c++/4.3/bits/stl_tree.h:1148
#3 0xb74fab2d in std::set<std::string, std::less<std::string>, std::allocator<std::string> >::insert (this=0x97bf918, __x=@0xaabfc1c4)
at /usr/include/c++/4.3/bits/stl_set.h:381
有什么想法吗?
修改
更多代码:
set<string> dangerous_messages; //placed in header file
qpid::client::Message msg;
msg = (*mylocal_queues)[queue]->get(10*1e9);
string msgUID = msg.getHeaders().getAsString("UID");
if(this->dangerous_messages.count(msgUID))
{
warning("(read_local_queue) Duplicate message \""+msgUID+"\" discarded");
}
else
{
msg.getHeaders().setString("BID", bid);
this->dangerous_messages.insert(msgUID);
}
使用gdb打印,我没有注意到集合或字符串中的任何损坏。
答案 0 :(得分:5)
问题也可能位于其他地方。程序中某些其他位置的溢出可能会在您插入集合时导致段错误。插入只是识别错误的时间点,但根本不一定与错误有关。
考虑这个组成的例子:
vector<MyObj*> ptrs;
if/for/while (...)
{
MyObj o;
ptrs.push_back(&o);
} // end of scopre for o
// Your heap is corrupted, but no segfault has to occur right away
...
// Your insertion occurs somewhere later
// No the program segfaults because of the problem you created earlier
答案 1 :(得分:4)
由于您声明代码是多线程而没有锁定,这可能是竞争条件的结果。 (至少一个竞争条件可能会导致完全相同的堆栈跟踪。)
使用正确的锁以确保正确执行。例如,如果您使用的是OpenMP,请将您向我们展示的代码更改为:
#pragma omp critical
{
if(this->dangerous_messages.count(msgUID))
{
warning("(read_local_queue) Duplicate message \""+msgUID+"\" discarded");
}
else
{
msg.getHeaders().setString("BID", bid);
this->dangerous_messages.insert(msgUID);
}
}
但总的来说,如果发生这样的错误,你的代码逻辑基本上是有缺陷的。 在没有干净的跨线程接口的情况下,您不能在线程之间共享状态。使用预定义的跨线程通信结构在线程之间共享状态,或使用只读状态。跨线程写入几乎都不行。
答案 2 :(得分:0)
您的堆可能已损坏,您的字符串或设置实例可能已被破坏。
答案 3 :(得分:0)
狂野猜测:包含my_set
的对象已经超出范围/已被销毁。
如果您想要更精确的答案,则必须发布更多代码。