我创建了一个类“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
}
我期望代码对矢量进行排序,但它会进入分段错误。
您的程序在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){};