使用STL deque的分段故障

segfault using STL deque

本文关键字:分段 故障 deque STL 使用      更新时间:2023-10-16

当循环到达810迭代时,我的代码出现了一个奇怪的段错误(见下文),我不知道为什么会发生这种情况。我使用了valgrind,但是它泄漏了一个无法理解的错误,我认为这个错误来自stl,导致读取无效的内存地址。不久前,在第49次迭代时,它报错了一个警告:在一个64字节的空闲块中,有一个48字节的地址。

它最后说"0x8没有堆栈,malloc或(最近)释放",并且发生段错误的行是粘贴的第78行,其中el在de循环中第一次被访问,所以看起来我应该击中队列的末尾,但事实并非如此,由于第74行。

#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <gsl/gsl_math.h>
#include <gsl/gsl_monte.h>
#include <gsl/gsl_monte_plain.h>
#include <gsl/gsl_monte_miser.h>
#include <gsl/gsl_monte_vegas.h>
using namespace std;
const int D=1;
double f(double *x,size_t n,void *params){
  if(-1. <= x[0] && x[0] <= 1. )
    return 0.75*(1.-(x[0]*x[0]));
  else
    return 0;
}
double g(double *x,size_t n,void *params){
  if(-1. <= x[0] && x[0] <= 1. )
    return 1.5*(x[0]*x[0]);
  else
    return 0;
}
typedef struct domain{
    int good;
    double xi[D],xf[D];
    double S;
} domain;
int main(){
  int i,j,k,counter=0;
  double cutoff=0.025,S,err;
  domain mdel,tdel;
  deque <double> lside,rside;
  deque <double> :: iterator lel,rel;
  deque <domain> dom;
  deque <domain> :: iterator el;
  //double xi[D], xf[D];
  double xi,xf;
  size_t calls = 500000;
  gsl_monte_function F;
  const gsl_rng_type *T;
  gsl_rng *r;
  //gsl_monte_vegas_state *s = gsl_monte_vegas_alloc (D);
  gsl_monte_miser_state *s_m=gsl_monte_miser_alloc (D);
  T = gsl_rng_default;
  r = gsl_rng_alloc (T);
  F.f = &f;
  F.dim=D;
  F.params=NULL;
  mdel.good=0;
  mdel.xi[0]=-1.;
  mdel.xf[0]=1.;
  mdel.S=1.0;
  //lside.push_back(-1.0);
  //rside.push_back(1.0);
  dom.push_back(mdel);
  //while()
  for(el=dom.begin();el!=dom.end();el++){
    //for(i=0;i<D;i+=1){xi[i]=el->xi[i];xf[i]=el->xf[i];}
    S=0.0;
    if(el==dom.end())
      cout<< "end of dequen";
    //xi[0]=el->xi[0];
    //xf[0]=el->xf[0];
    xi=el->xi[0];
    xf=el->xf[0];
    //xi=*lel;
    //xf=*rel;
    gsl_monte_miser_integrate(&F,&xi,&xf,D,calls,r,s_m,&S,&err);
    //gsl_monte_vegas_integrate (&F, &xi, &xf, D, 10000, r, s,&S, &err);
    //do{
    //  gsl_monte_vegas_integrate (&F, &xi, &xf, D, calls/5, r, s,&S, &err);
    //}while (fabs (gsl_monte_vegas_chisq (s) - 1.0) > 0.5);
    el->S=S;
    cout << "size & maxsize:  " << dom.size() << "  "<< dom.max_size() << "n";
    cout<< "counter @ " << counter << " ";
    //cout << "[" << xi[0] << "," << xf[0] << "] : ";
    cout << "[" << xi << "," << xf << "] : ";
    cout << "S= " << S << " +- " << err << "  :  " << 0.75*(xf-xi-(xf*xf*xf-xi*xi*xi)/3.0) <<"nn";
    if(S > cutoff){
      el->good=1;
      tdel.good=0;
      tdel.xi[0]=el->xi[0];
      tdel.xf[0]=(el->xi[0]+el->xf[0])/2.;
      tdel.S=0.0;
      dom.push_back(tdel);
      //lside.push_back(tdel.xi[0]);
      //rside.push_back(tdel.xf[0]);
      tdel.good=0;
      tdel.xi[0]=(el->xi[0]+el->xf[0])/2.;
      tdel.xf[0]=el->xf[0];
      tdel.S=0.0;
      dom.push_back(tdel);
      //lside.push_back(tdel.xi[0]);
      //rside.push_back(tdel.xf[0]);
    }
    counter++;
  }
  //gsl_monte_vegas_free (s);
  gsl_monte_miser_free (s_m);
  gsl_rng_free (r);
  return 0;
}

如果有人能帮我,我将非常感激。

注。代码不需要任何输入,所以它只是编译和链接到GSL

当您在for循环的中间向deque dom添加元素时,您将使el迭代器失效。

来自问题Iterator invalidation rules:

<标题>插入

序列容器
  • vector:插入点之前的所有迭代器和引用不受影响,除非新容器的大小大于先前容量(在这种情况下,所有迭代器和引用都是)无效)[23.2.4.3/1]
  • deque:所有迭代器和引用都无效,除非插入的成员位于deque的末端(前端或后端)Case所有迭代器都无效,但对元素的引用无效不受影响)[23.2.1.3/1]
  • list:所有迭代器和引用不受影响[23.2.2.3/1]