C++ std::sort()中的程序崩溃有时会';复制 说明:

C++ std::sort()中的程序崩溃有时会';复制 说明:,c++,vector,stl,crash,C++,Vector,Stl,Crash,我的程序有时会崩溃在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<

我的程序有时会崩溃在
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;
}
下面是发生崩溃的一段代码:

 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);
article_result->clear();
对于(vec_iter=\u channel_data->begin();vec_iter!=\u channel_data->end();vec_iter++){
cand_article*cand=to_cand_group(*vec_iter);
如果(cand==NULL)继续;
//刷新打开的loadmore
if(m_request.req_type==1){
if(cand->display_time>m_request.start){
文章结果->推回(cand);
}
}else if(m_request.req_type==2){
if(cand->display_time推回(cand);
}
}否则{
文章结果->推回(cand);
}
}
排序(article\u result->begin(),article\u result->end(),article\u cmp);
问题: 我不知道如何处理这种
coredump
,因为
0x4015
是内核空间地址吗?有没有关于如何修复此类错误的建议?抱歉,我无法用最小的程序重现这种情况。这发生在一个
单线程
,所以你不需要考虑
多线程
的情况。

规则是“如果
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;
}
您的简化示例之所以有效(祝贺您至少尝试了简化),是因为您简化了比较函数,使其有效。如果返回语句是
returns1->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
};
<代码>结构{{//不需要C++中的Type 内特; char ch; std::string charr;//…或*可能*std::array。 std::vector vs;//字符串和向量最好由值保存 };
还请注意,我实际上使用了
std::
前缀。

规则是“如果
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;
}
您的简化示例之所以有效(祝贺您至少尝试了简化),是因为您简化了比较函数,使其有效。如果返回语句是
returns1->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
};
<代码>结构{{//不需要C++中的Type 内特; char ch; std::string charr;//…或*可能*std::array。 std::vector vs;//字符串和向量最好由值保存 };
还要注意,我实际上使用了
std::
前缀

  • 您的最小程序正在发生内存泄漏。因为它只是从列表中删除所有项目,但没有释放它们使用的内存。如果项目足够大,程序可能会在耗尽所有内存后崩溃。这就是为什么你的最小程序仍然可以,因为那里的项目非常小

  • 我会将您的计划更改为:

    类型定义结构st{ 内特; char ch; char-charr[100]; 向量*vs; }st

    布尔函数(st*&s1、st*&s2){ 静态int i=1; couts2->it; }

    int main(int argc,字符**argv){ 向量ar; 对于(int i=0;i<100;++i){ st*s=新的st; s->it=urandom32(); ar.推回(s); }

    首先释放我的ar项目使用的所有内存 for(vector::iterator it=ar.begin();it!=ar.end();++it) 删除*它

    ar.clear()

    for(int i=0;i<100;++i){
    st*s=新的st;
    s->it=urandom32();
    ar.推回(s);
    }
    排序(ar.begin(),ar.end(),函数);
    返回0;
    
    }

  • 您的最小程序正在发生内存泄漏。因为它只是从列表中删除所有项目,但没有释放它们使用的内存。如果项目足够大,程序可能会在耗尽所有内存后崩溃。这就是为什么你的最小程序仍然可以,因为那里的项目非常小

  • 我会将您的计划更改为:

    类型定义结构st{ 内特; char ch; char-charr[100]; 向量*vs; }st

    布尔函数(st*&s1、st*&s2){ 静态int i=1; couts2->it; }

    int main(int argc,字符**argv){ 向量ar; 对于(int i=0;i<100;++i){ st*s=新的st; s->it=urandom32(); ar.推回(s); }

    首先释放我的ar项目使用的所有内存 for(vector::iterator it=ar.begin();it!=ar.end();++it) 删除*它

    ar.clear()

    for(int i=0;i<100;++i){
    st*s=新的st;
    s->it=urandom32();
    ar.推回(s);
    }
    排序(ar.begin(),ar.end(),函数);
    返回0;
    
    }


  • 0x4015不是内核地址,但它可能是损坏的指针,或者是取消引用空指针中的成员的结果。但是,您的
    article\u cmp()
    函数似乎与您发布的其他代码没有任何关系,所以发生了什么?你有没有人可以编译和运行的代码也会崩溃?@nos我粘贴了一个