描述:
我的程序有时会在 std::sort()
中崩溃,我写了一个最小的程序来重现这种情况,但一切都很好。这是最小的例子:
typedef struct st {
int it;
char ch;
char charr[100];
vector<string *> *vs;
} st;
bool function(st *&s1, st *&s2) {
static int i = 1;
cout<<i<<" "<<&s1<<" "<<&s2<<endl;
++i;
return s1->it > s2->it;
}
int main(int argc, char **argv) {
vector<st *> ar;
for (int i = 0; i < 100; ++i) {
st *s = new st;
s->it = urandom32();
ar.push_back(s);
}
ar.clear();
for (int i = 0; i < 100; ++i) {
st *s = new st;
s->it = urandom32();
ar.push_back(s);
}
sort(ar.begin(), ar.end(), function);
return 0;
}
这是 GDB 堆栈信息:
- 0 0x00007f24244d9602 in article_cmp (cand_article_1=0x7f23fd297010, cand_article_2=0x4015) at src/recom_frame_worker.h:47
- 1 0x00007f24244fc41b in std::__unguarded_partition<__gnu_cxx::__normal_iterator > >, cand_article*, bool ()(cand_article, cand_article*)> (__first=, __last=, __pivot=@0x7f230412b350: 0x7f23fd297010, __comp=0x7f24244d95e1 ) at /usr/include/c++/4.8.3/bits/stl_algo.h:2266
- 2 0x00007f24244f829c in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator > >, bool ()(cand_article, cand_article*)> (__first=, __last=, __comp=0x7f24244d95e1 ) at /usr/include/c++/4.8.3/bits/stl_algo.h:2296
- 3 0x00007f24244f1d88 in std::__introsort_loop<__gnu_cxx::__normal_iterator > >, long, bool ()(cand_article, cand_article*)> (__first=, __last=, __depth_limit=18, __comp=0x7f24244d95e1 ) at /usr/include/c++/4.8.3/bits/stl_algo.h:2337
- 4 0x00007f24244ed6e5 in std::sort<__gnu_cxx::__normal_iterator > >, bool ()(cand_article, cand_article*)> ( __first=, __last=, __comp=0x7f24244d95e1 ) at /usr/include/c++/4.8.3/bits/stl_algo.h:5489
article_cmp
在 sort(article_result->begin(), article_result->end(), article_cmp);
中调用article_result 是 vector<cand_article*> *
. cand_article
是一个结构。
这是 article_cmp
的定义:
bool article_cmp(cand_article* cand_article_1, cand_article* cand_article_2) {
return cand_article_1 -> display_time >= cand_article_2 -> display_time;
}
这是发生崩溃的一段代码:
article_result->clear();
for(vec_iter = _channel_data -> begin(); vec_iter != _channel_data -> end(); vec_iter++) {
cand_article* cand = to_cand_group(*vec_iter);
if(cand == NULL) continue;
// refresh open loadmore
if(m_request.req_type == 1) {
if(cand -> display_time > m_request.start){
article_result->push_back(cand);
}
}else if(m_request.req_type == 2){
if(cand -> display_time < m_request.end){
article_result->push_back(cand);
}
}else{
article_result->push_back(cand);
}
}
sort(article_result->begin(), article_result->end(), article_cmp);
问题:
我不知道如何处理这种coredump
, 导致 0x4015
是内核空间地址?关于如何修复此类错误的任何建议?抱歉,我无法用最小程序重现这种情况。这发生在 single thread
,所以你不需要考虑 multi-thread
情况。
最佳答案
规则是“如果 std::sort
崩溃,你有一个无效的比较函数”。你的比较函数是:
bool article_cmp(cand_article* lhs, cand_article* rhs) {
return lhs -> display_time >= rhs -> display_time;
}
这不是严格的弱排序。特别是,如果显示时间相等,它会返回 true
,这意味着如果您交换参数,它仍然会返回 true
...这是不允许的。你需要:
bool article_cmp(cand_article* lhs, cand_article* rhs) {
return lhs -> display_time > rhs -> display_time;
}
您的简化示例起作用的原因(祝贺您至少尝试 进行了简化)是您简化了比较函数,因此它是有效的。如果 return 语句是 return s1->it >= s2->it;
,并且您使用了较小范围的值,它也可能会崩溃。
顺便说一句,您的示例结构的更自然的 C++ 声明如下所示:
struct st { // No need for that typedef in C++
int it;
char ch;
std::string charr; // ... or *possibly* std::array<char,100>.
std::vector<std::string> vs; // Strings and vectors best held by value
};
另请注意,我实际上使用了 std::
前缀。
关于c++ - std::sort() 中的程序有时会崩溃,无法重现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40483971/