插入集合时崩溃
Crash while inserting int a set
我的程序在将 和 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
来保护您的 set 插入块。
重要编辑: boost::shared_ptr<>
can't assumed to be thread safe. In the examples on boost.org, they suggest that a shared pointer going out of scope might cause a race. It may therefore be highly advisable to follow Matthew Moss在评论中的建议并使用原始指针指向范围内的集合process_set()。
我的程序在将 和 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
来保护您的 set 插入块。
重要编辑: boost::shared_ptr<>
can't assumed to be thread safe. In the examples on boost.org, they suggest that a shared pointer going out of scope might cause a race. It may therefore be highly advisable to follow Matthew Moss在评论中的建议并使用原始指针指向范围内的集合process_set()。