使用STL deque的段错误

时间:2014-07-29 01:53:19

标签: c++ stl gsl

当循环到达81o迭代时,我的代码(见下文)出现了一个奇怪的段错误,我不知道它为什么会发生。我使用了valgrind,但它泄漏了一个难以理解的错误,我把它来自stl,导致读取无效的内存地址。前一段时间,在49o迭代中,它发出一个警告,即在一个64字节的块之一内有一个48字节的地址空闲&#d; d。

它结束说" 0x8不是堆栈' d,malloc&d;或者(最近)自由' d",它发生的行是段错误是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 deque\n";
    //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) <<"\n\n";

    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;
}

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

p.s。:代码不需要任何输入,所以它只是编译并链接到GSL

1 个答案:

答案 0 :(得分:2)

el循环中间向deque dom添加元素时,您使for迭代器无效。

问题Iterator invalidation rules

插入

序列容器

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