如何根据大小修复“分段错误(核心转储)”

问题描述 投票:0回答:1

我创建了一个类“config”,其中包含12个bool值,以std :: array组织。该类具有返回double值的“icing”函数。尝试使用我编写的谓词通过std :: sort(包含在#include中)命令2 ^ 12(4096)配置的向量,我得到了分段错误错误。

将向量缩小到205(不是1)可以消除错误,但我不知道为什么。如果我使矢量4096长,并尝试只对一小部分进行排序,它可以工作,直到该部分长175+。将矢量缩小到例如大约1000,将部分排序限制在20左右,然后才会给出分割错误。

#include <array>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std; 

class config {
public: 
    config (){       //constructor, default
        array<bool,12> t;
        for (bool& b: t){
            b=false;
        }
        val=t;
        g=1;
    }
    config (const config& fro): val(fro.val){};   //copy constructor
    array<bool,12> get_val(){ return val; }  //returns the array
    void set_tf(int n, bool tf){ val[n]=tf; }  //sets a certain boolean     in the array to false/true
    void set_g(double d){ g=d; }  //this sets the constant for     calculation to a number
    void print(){
        cout<<"values: ";
        for (auto b: val){ cout<<b<<" "; }
        cout<<endl;
    }
    config & incr(int n=1){ //this increases the vector by 1 following the rules for binary numbers, but has the digits reversed
        for(int j=0; j<n; j++){
            int i=0;
            bool out=false;
            while(val[i]==true){
                val[i]=false;
                i++;
            }
            val[i]=true;
        }
        return *this;
    }   
    double energy(){
        int ct=0;
        int cf=0;
        for(auto b:val){ if(b==true){ ct++; } else { cf++; } }
        return (abs(ct-cf));
    }
    double icing(){        //here is the "value" for ordering purposes
        int n=0;
        for(int i=0; i<11; i++){
            if(val[i]!=val[i+1]){ n++; }
        }
        double temp=-g*n+this->energy();
        return temp;
    }
private:
    array<bool,12> val;
    double g;
};

bool pred (config c1, config c2){ return c1.icing()>c2.icing(); }     //this sets the ordering predicate

template <typename T>    //this orders the vector
void csort (vector <T>& in){
    sort(in.begin(), in.end(), pred);
}

int main(){
    vector<config> v;
    for (int i=0; i<4096; i++){ //cicle that creates a vector of successive binaries
        for(auto& c:v){
            c.incr();
        }
        config t;
        v.push_back(t);
    }
    sort(v.begin(), v.begin()+174, pred);   //this gives seg.fault when 175+
    csort(v);           //this gives segmentation fault when the vec is 206 long or longer
}

我期望代码对矢量进行排序,但它会进入分段错误。

c++11
1个回答
0
投票

您的程序在sort函数中有未定义的行为,因为您的谓词按值获取config,因此复制是在这个地方复制构造函数被调用,它只复制数组val,但不复制g

bool pred (config c1, config c2){ return c1.icing()>c2.icing(); } 
//         takes by value, copy ctor is called 
config (const config& fro): val(fro.val){}; // only val is copied, g HAS GARBAGE VALUE
// icing in pred uses g !! - stric weak ordering is violated because g has GARBAGE VALUE

修复1:通过const config&传递配置:

bool pred (const config& c1, const config& c2){ return c1.icing()>c2.icing(); }

或修复2:g在复制构造函数中初始化:

config (const config& fro): val(fro.val), g(fro.g){};
© www.soinside.com 2019 - 2024. All rights reserved.