2014-10-15 2 views
-1

bspline 기반 함수를 평가하기위한 클래스를 정의했습니다. 나는 클래스는 다음 등등 어디 사용 포인터를, 또는 새로운 삭제합니다함수 인수 정의에 따라 함수가 충돌 함 - 이중 자유 또는 손상

class bspline_basis{ 

    //private: 
    public: 
      int k;           /*! order of Bspline basis */ 
      int nbreak;          /*! Dimension of breakpoints vector. */ 
      int nknots;          /*! Dimension of knots vector. */ 
      int nbasis;          /*! Number of basis functions */ 




      vector<double> breakpts;      /*! Represents strictly increasing values of knots, excluding all multiplicities */ 
      vector<double> knots;       /*! Raw knot vector of BSpline basis, it may contain multiple entries due to multiplicity */ 

      vector<double> Bix_nonzero;      /*! size: (k). Stores nonzero components of bspline basis */ 
      vector<double> Bix;        /*! size: nbasis Stores all components of bspline basis. Not necessary - remove? */ 


      int find_knot_span_of_x(const double &x);          /*! Returns integer i: t_i <= x < t_{i+k}. Upon call it stores i in i_saved */   
      pair<int,int> find_nonzero_basis_at_x(const double &x);       /*! Returns first, last index of nonzero basis B_i(x) at particular x. */ 
      pair<int,int> find_base_nonzero_interval(const double &x);      /*! Returns first (i) , last (i+k) index of knots t_i at particular x. */ 


      int i_saved; // Temporary saves for speed up 
      double x_saved; // Temporary saves for speed up 

      /* !ESSENTIAL ROUTINES FOR EVALUATION! Add as optional argument another knot vector for use in evaluation of integrals */ 
      void eval_nonzero_basis(const int &i, const double &x);   /*! Evaluates non zero basis functions at x */ 
      void eval_Bix(const int &i, const double &x);     /*! Evaluates all basis functions at x */ 

      /*! Default clamped knot vector constructor */ 
      bspline_basis(const vector<double> &_breakpts, const int &_k); 
      /* Evaluation functions */ 
      double get_Bix(const int &i, const double &x);     /*! Value B_i(x) */ 


}; 

사용자에게 투명하고 B_i (x)가 함수입니다 평가 기능

get_Bix(const int &i, const double &x); 

I을 for 루프 내에서 변수 정수 i와 함께 사용하면 모든 것이 잘 작동합니다. 즉,이 예제에서는 다음과 같습니다.

// some constructor of class mybasis 
for(double x=0; x<=10. x+=0.01) 
    { 
    cout<< x << " "; 
    for (int i=0; i<nbasis; ++i) 
      cout<< mybasis.get_Bix(i,x)<<" "; 
    cout<<endl; 
    } 

올바른 값이 인쇄됩니다.

int idx=3; 
for(double x=0; x<=10. x+=0.01) 
    { 
    cout<< x << " "; 
    //for (int i=0; i<nbasis; ++i) 
      cout<< mybasis.get_Bix(idx,x)<<" "; 
    cout<<endl; 
    } 

나는 다음과 같은 오류가 발생합니다 : :이 예에서와 같이 함수의 첫 번째 인수에 대한 일정한 정수를 정의하지만 경우

*** Error in `./test_class.xxx': double free or corruption (out): 0x0000000000740280 *** 

내가 GDB의 코드를 실행하고 역 추적 그것은, 나는 다음과 같은 메시지가 얻을 :

(gdb) bt 
#0 0x00007ffff7530bb9 in __GI_raise ([email protected]=6) at ../nptl/sysdeps/unix/sysv/linu/raise.c:56 
#1 0x00007ffff7533fc8 in __GI_abort() at abort.c:89 
#2 0x00007ffff756de14 in __libc_message ([email protected]=1, [email protected]=0x7ffff767c668 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 
#3 0x00007ffff757a0ee in malloc_printerr (ptr=<optimised out>, str=0x7ffff767c798 "double free or corruption (out)", action=1) at malloc.c:4996 
#4 _int_free (av=<optimised out>, p=<optimised out>, have_lock=0) at malloc.c:3840 
#5 0x00000000004039ac in __gnu_cxx::new_allocator<double>::deallocate (this=0x7fffffffdc70, __p=0x608280) at /usr/include/c++/4.8/ext/new_allocator.h:110 
#6 0x00000000004031be in std::_Vector_base<double, std::allocator<double> >::_M_deallocate (this=0x7fffffffdc70, __p=0x608280, __n=15) at /usr/include/c++/4.8/bits/stl_vector.h:174 
#7 0x00000000004030b3 in std::_Vector_base<double, std::allocator<double> >::~_Vector_base (this=0x7fffffffdc70, __in_chrg=<optimised out>) at /usr/include/c++/4.8/bits/stl_vector.h:160 
#8 0x00000000004028ed in std::vector<double, std::allocator<double> >::~vector (this=0x7fffffffdc70, __in_chrg=<optimised out>) at /usr/include/c++/4.8/bits/stl_vector.h:416 
#9 0x00000000004017aa in bspline_basis::eval_Bix (this=0x7fffffffdd40, ii=4, [email protected]: 0.01) at bsplines_stackoverflow.hpp:247 
#10 0x0000000000401f59 in bspline_basis::get_Bix (this=0x7fffffffdd40, i=4, [email protected]: 0.01) at bsplines_stackoverflow.hpp:331 
#11 0x000000000040214e in main() at test_class.cpp:31 

문제는 기능에 거짓말을해야합니다

double bspline_basis::get_Bix(const int &i, const double &x) 
    { 

    if (i<0 || i> nbasis){ 
    DEBUG(i); 
    std::cerr<< "Index of Bix out of range, aborting ..." << endl; 
    throw 0; 
    } 

    if (x==x_saved && i==i_saved) { 
      return 
        Bix[i]; 
    }else if (x != x_saved && i == i_saved){ 

      eval_Bix(i_saved,x); // Evaluate all nonzero and store to Bix. 
      x_saved=x;    // Store x for subsequent evaluations. 

      return 
        Bix[i]; 

    }else { 

      // a. Find knot span of x: 
      find_knot_span_of_x(x); 
      // b. Evaluate all nonzero Bix and pass them to Bix: 
      eval_Bix(i_saved,x); 

      x_saved=x;    // Store x for subsequent evaluations. 
      i_saved=i;    // Store knot span i for possible subsequent evaluations. 

      return 
        Bix[i]; 

    } 



} 

/*! 
Wrapper function for eval_nonzero_basis. Passes nonzero basis values to vector<double> Bix. 
*/ 
void bspline_basis::eval_Bix (const int &ii, const double &x){ 

    //pair<int,int> i_start_end = find_nonzero_basis_at_x(x); 
    int istart= ii-k+1; 
    pair<int,int> i_start_end = make_pair(istart,ii); 

    // Evaluate all nonzero entries. for this index. 
    eval_nonzero_basis(i_start_end.second, x); 

    // Initialize (to zeros) temporary vector of dimension nbasis 
    vector<double> Bix_temp(nbasis,0.0); 

    // Pass nonzero entries to temporary vector 
    for(int j= i_start_end.first; j <= i_start_end.second; ++j) 
      Bix_temp[j] = Bix_nonzero[j-i_start_end.first]; 

    // move temporary vector to Bix 
    Bix=Bix_temp; 
} 

나는 내가 루프 외부의 첫 번째 인수를 정의 할 때 오류를 얻을 수 있습니다 방법을 이해 할 수 없다. 어떤 도움을 많이 주셨습니다.

업데이트 : 색인 (idx = 3)이 허용 된 범위 간격을 벗어 났기 때문에 문제가 아니라는 점을 분명히 해주세요. 이 경우 첫 번째 for 루프가 중단됩니다. 변수 nbasis는 3보다 훨씬 큽니다.

업데이트 2 : @Adrian 제안에 따라 Bix_temp를 클래스의 요소로 만들고 코드를 다시 실행했습니다. 다시 코드가 충돌하지만 출력 (값 x 및 infs)이 생성된다는 것을 알고 있습니다.

9.97 inf 
9.98 inf 
9.99 inf 
10 inf 
0.002867sec 
4.78333e-05min 
*** Error in `/home/foivos/Documents/Grav_Ast/BSplines/Genetic_Algorithms/tests/test_new_Jeans/bsplines_class/test_class.xxx': double free or corruption (out): 0x0000000000608180 *** 

Program received signal SIGABRT, Aborted. 
0x00007ffff7530bb9 in __GI_raise ([email protected]=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. 
(gdb) bt 
#0 0x00007ffff7530bb9 in __GI_raise ([email protected]=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 
#1 0x00007ffff7533fc8 in __GI_abort() at abort.c:89 
#2 0x00007ffff756de14 in __libc_message ([email protected]=1, [email protected]=0x7ffff767c668 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 
#3 0x00007ffff757a0ee in malloc_printerr (ptr=<optimised out>, str=0x7ffff767c798 "double free or corruption (out)", action=1) at malloc.c:4996 
#4 _int_free (av=<optimised out>, p=<optimised out>, have_lock=0) at malloc.c:3840 
#5 0x00000000004039e8 in __gnu_cxx::new_allocator<double>::deallocate (this=0x7fffffffdda8, __p=0x608180) at /usr/include/c++/4.8/ext/new_allocator.h:110 
#6 0x00000000004031fa in std::_Vector_base<double, std::allocator<double> >::_M_deallocate (this=0x7fffffffdda8, __p=0x608180, __n=15) at /usr/include/c++/4.8/bits/stl_vector.h:174 
#7 0x00000000004030ef in std::_Vector_base<double, std::allocator<double> >::~_Vector_base (this=0x7fffffffdda8, __in_chrg=<optimised out>) at /usr/include/c++/4.8/bits/stl_vector.h:160 
#8 0x0000000000402929 in std::vector<double, std::allocator<double> >::~vector (this=0x7fffffffdda8, __in_chrg=<optimised out>) at /usr/include/c++/4.8/bits/stl_vector.h:416 
#9 0x0000000000402646 in bspline_basis::~bspline_basis (this=0x7fffffffdd30, __in_chrg=<optimised out>) at bsplines_stackoverflow.hpp:57 
#10 0x00000000004022b6 in main() at test_class.cpp:22 
(gdb) frame 9 
#9 0x0000000000402646 in bspline_basis::~bspline_basis (this=0x7fffffffdd30, __in_chrg=<optimised out>) at bsplines_stackoverflow.hpp:57 
57 class bspline_basis{ 
(gdb) info args 
this = 0x7fffffffdd30 
__in_chrg = <optimised out> 
(gdb) 

이 다시 제가 루프 인덱스에 대해 사용할 때 나는 오류를 얻을하지 않습니다 강조하자 :이 디버거의 새로운 출력됩니다.

업데이트 3 :이 버그를 발견, 그것은 코드의 다음 줄에, 개념과 기능을 구체적으로

get_Bix(const int &i, const double &x) 

내부했다 :

// Was using the same index i, for different x, which was a mistake and was causing troubles. 
}else if (x != x_saved && i == i_saved){ 

     eval_Bix(i_saved,x); // Evaluate all nonzero and store to Bix. 
     x_saved=x;    // Store x for subsequent evaluations. 

     return 
       Bix[i]; 

}else { 

는 당신의 도움에 대해 감사합니다.

+2

보통 디버거의 목적은 SO 질문이 아닙니다. –

+0

흠. 그것은 내가 두 개 이상의 무료로 보이지 않기 때문에 나는 그 문제가 아마도 당신의 벡터 중 하나 이상의 범위를 벗어나서 밟아서 발생하는 손상이라고 가정합니다. – drescherjm

답변

2

시도 :

if (i<0 || i>= nbasis){ 

대신 get_Bix의 상단에

if (i<0 || i> nbasis){ 

의. 이 스택 추적에 소멸자, 그리고 그것의를해야합니다

당신이 구성 요소 0, 1, 2를해야하는 경우에 당신이 3D에있어 같은데요

,하지만 3

+0

안녕하세요 덕분에 문제는 기본의 차원에 있지 않습니다. 왜냐하면 나는 15 개의 계수를 가지고 있습니다. 즉, [0,14]에 있습니다. 따라서 idx = 3이 범위 내에 있습니다. 당신의 답변에 감사드립니다. – Foivos

0

eval_Bix의 끝에있는 Bix_temp.

나는 왜 그것이 일어나고 있는지 정말로 모르지만, Bix_temp를 클래스의 멤버로 만드는 것은 거의 확실하게 그것을 고칠 것이다. 그럴 때마다 매번 제로화하는 번거 로움이 있지만, 어쨌든 건설과 파괴보다 빠릅니다.

+0

안녕하세요 애드리안, 다시 한 번 감사드립니다. 나는 당신이 말한 것을 따라 갔고 문제를 해결하지 못했습니다. 변수가 int idx에 의해 문제가 (어쨌든?) 발생했습니다. 주목할만한 점은 for 루프의 첫 번째 버전에는 문제가 없다는 것입니다. 다시 고마워. – Foivos

+0

Buoah! 이것은 더러운 것입니다. 새 스택 추적을 게시 할 수 있습니까? 오래된 하나는 evalBix 내부의 이중 벡터의 소멸자에 충돌하고 있다고했습니다. 내가 말한 것을 정말로 수행했다면 eval_Bix에 벡터의 소멸자가 없으므로 스택 추적이 변경되었을 것입니다. 당신의 "왜 그것은 그 int에 달려 있습니까?"논리에 관해서, 내가 말할 수있는 것은 과거에는 그런 생각만으로 두통을 겪어 본 적이 있다는 것입니다. –

관련 문제