我的程序在将 和 int 插入集合时似乎崩溃了,我无法找出原因。相关代码如下:
bool request::check_list(std::vector<int> search_vec)
{
std::set<int> *tmp_ptr = create_int_set();
boost::shared_ptr<std::set<int> > c_list(tmp_ptr);
if(aerospike_query_foreach(as, &err, NULL, &query, process_set, &c_list) != AEROSPIKE_OK)
{
return false;
}
for(int i = 0; i < search_vec.size(); i++)
{
if(c_list->find(search_vec[i]) != c_list->end())
{
c_list_value_ = search_vec[i];
return true;
}
}
return false;
}
bool request::process_set(const as_val *val, void * udata)
{
try
{
boost::shared_ptr<std::set<int> > c_set = *(boost::shared_ptr<std::set<int> > *)(udata);
if(val == NULL)
{
return true;
}
if(val->type == AS_REC)
{
if (val!=NULL)
{
as_record *rec = as_record_fromval(val);
if (rec!=NULL)
{
as_integer* c_id = as_record_get_integer(rec,"c_id");
int cid = 0;
cid = boost::lexical_cast<int>(c_id->value);
if(c_set != nullptr)
{
c_set->insert(c_id);
}
as_record_destroy(rec);
as_integer_destroy(c_id);
}
}
return true;
}catch(...){}
return false;
}
行c_set->insert(c_id);
导致了段错误。这是崩溃的回溯:
#0 0x00007f2064299f94 in std::_Rb_tree_rotate_right(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*&) () from /usr/lib64/libstdc++.so.6
#1 0x00007f206429a12b in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /usr/lib64/libstdc++.so.6
#2 0x00000000004829d9 in std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_insert_<int const&> (this=0x7f1fcc005440, __x=0x0, __p=0x7f1f3c0009a0, __v=@0x7f20159e729c)
at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_tree.h:981
#3 0x000000000047f1e0 in std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_insert_unique<int const&> (this=0x7f1fcc005440, __v=@0x7f20159e729c)
at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_tree.h:1299
#4 0x000000000047c473 in std::set<int, std::less<int>, std::allocator<int> >::insert (this=0x7f1fcc005440, __x=@0x7f20159e729c)
at /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_set.h:415
#5 0x00000000004765ee in request::process_set (val=0x7f20159e73e0, udata=0x7f200b9d6620) at ../../request.cpp:1862
我假设存在集合未初始化的问题,或类似的问题。以下是我如何从另一个函数创建和传递该集合,我尝试了两种方法来创建它:
boost::shared_ptr<std::set<int> > c_list(new std::set<int>());
和
std::set<int> *tmp_ptr = create_int_set();
boost::shared_ptr<std::set<int> > c_list(tmp_ptr);
std::set<int>* request::create_int_set()
{
return new std::set<int>();
}
调用函数是来自数据库驱动程序的回调函数,它接受一些不同的对象,但最值得注意的是 process_set 和 c_list,它们作为 void* 传递:
aerospike_query_foreach(as, &err, NULL, &query, process_set, &c_list)
这种崩溃并不总是发生,事实上,这种情况相当罕见,这让我觉得我做错了什么,某种未定义的行为。任何帮助将不胜感激!
最佳答案
aerospike APi documentation对于回调来说(即 process_set()
,此处):
Execute a query and call the callback function for each result item. Multiple threads will likely be calling the callback in parallel. Therefore, your callback implementation should be thread safe.
由于多个线程可能同时插入同一集合(共享指针指向的集合)中,因此您将遇到竞争条件,从而出现未定义的行为!
所以我认为你至少应该用 lock_guard
来保护你的设置插入 block 。在互斥锁上。
重要编辑: boost::shared_ptr<>
can't assumed to be thread safe 。在 boost.org 上的示例中,他们建议共享指针超出范围可能会导致竞争。因此,强烈建议遵循 Matthew Moss 评论中的建议,并使用指向 process_set() 范围内的集合的原始指针。
关于c++ - 插入 int 集合时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32231888/