我的程序有时在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堆栈信息:
在article_cmp中的
- 0 0x00007f24244d9602(cand_article_1 = 0x7f23fd297010, cand_article_2 = 0x4015 ) 在src / recom_frame_worker.h:47
- 1 0x00007f24244fc41b in std :: __ unguarded_partition&lt; __ gnu_cxx :: __ normal_iterator&gt; &gt;中 cand_article *,bool()(cand_article ,cand_article *)&gt; (__first =, __last =,__ pivot = @ 0x7f230412b350:0x7f23fd297010, __comp = 0x7f24244d95e1) 在/ usr / include / c ++ / 4.8.3 / bits / stl_algo.h:2266
- 2 0x00007f24244f829c in std :: __ unguarded_partition_pivot&lt; __ gnu_cxx :: __ normal_iterator&gt; &gt;,布尔 ()(cand_article ,cand_article *)&gt; (__ first =,__last =, __comp = 0x7f24244d95e1) 在/ usr / include / c ++ / 4.8.3 / bits / stl_algo.h:2296
- 3 0x00007f24244f1d88 in std :: __ introsort_loop&lt; __ gnu_cxx :: __ normal_iterator&gt; &gt;,长, bool()(cand_article ,cand_article *)&gt; (__ first =,__last =, __depth_limit = 18, __comp = 0x7f24244d95e1) 在/ usr / include / c ++ / 4.8.3 / bits / stl_algo.h:2337
- 4 0x00007f24244ed6e5 in std :: sort&lt; __ gnu_cxx :: __ normal_iterator&gt; &gt;,布尔 ()(cand_article ,cand_article *)&gt; ( __first =,__last =,__ comp = 0x7f24244d95e1) 在/ 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
情况。
答案 0 :(得分:4)
规则是&#34;如果std::sort
崩溃,则您的比较功能无效&#34;。您的比较功能是:
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::
前缀。
答案 1 :(得分:0)
您的最小程序正在使内存泄漏。因为它只是从列表中删除所有项目但没有释放它们使用的内存。如果您的项目足够大,您的程序可能会在吃完所有内存后崩溃。这就是为什么你的最小程序仍然可以,因为那里的项目非常小。
我会将您的计划更改为:
typedef struct st { 在它; char ch; char charr [100]; 矢量* vs; } st;
bool函数(st *&amp; s1,st *&amp; s2){ static int i = 1; cout&lt; it&gt; S2-&gt;其; }
int main(int argc,char ** argv){ 矢量ar; for(int i = 0; i&lt; 100; ++ i){ st * s = new st; s-&gt; it = urandom32(); ar.push_back(一个或多个); }
for(vector :: iterator it = ar.begin(); it!= ar.end(); ++ it) 删除*它;
ar.clear();
.columns {
column-count: 2;
column-gap: 12px;
}
.columns p {
/* don't break paragraphs */
break-inside: avoid;
/* Use padding instead of margin to avoid weird space at top of the second column.*/
margin: 0;
padding-bottom: 14px;
}
}