2014-02-10 4 views
0

ODESolver 개체의 벡터를 만들어야합니다. ODESolver 객체를 만들면 모든 것이 정상입니다. 그러나 벡터를 사용하면 ODESolver 생성자가 호출 될 때 세그먼트 화 오류가 발생합니다. 왜 이런 경우이며 어떻게이 문제를 해결할 수 있습니까? 내가 gsl_odeiv_step_allocgsl_odeiv_step_free 같은데요GSL을 사용하여 ODE를 해결하기위한 객체 벡터를 만들 때 세분화 오류

#include <vector> 
#include <iostream>  
#include <gsl/gsl_errno.h> 
#include <gsl/gsl_odeiv.h> 
#include <gsl/gsl_matrix.h> 

struct ODESystem {}; 

struct ODESolver { 
    ODESolver(ODESystem &ODE_system) 
    { 
     d_solver_ptr = gsl_odeiv_step_rkf45; 
     d_step_ptr = gsl_odeiv_step_alloc(d_solver_ptr, d_dim_ODE); 
     d_evolve_ptr = gsl_odeiv_evolve_alloc(d_dim_ODE); 
    } 

    ~ODESolver() 
    { 
     gsl_odeiv_step_free(d_step_ptr); 
     gsl_odeiv_evolve_free(d_evolve_ptr); 
    } 

    const gsl_odeiv_step_type *d_solver_ptr; 
    gsl_odeiv_step *d_step_ptr; 
    gsl_odeiv_evolve *d_evolve_ptr; 
    gsl_odeiv_system d_ODE_system; 
    const static int d_dim_ODE = 4; 
}; 

struct MyODESystem : public ODESystem {}; 

int main() 
{ 
    MyODESystem myODE; 
    ODESolver mySolver(myODE);      // WORKS FINE 

    std::vector<MyODESystem> myODEVec; 
    myODEVec.push_back(MyODESystem()); 

    std::vector<ODESolver> mySolverVec; 
    mySolverVec.push_back(ODESolver(myODEVec[0])); // SEGMENTATION FAULT: 11 

    return 0; 
} 

답변

1

mallocfree 유사하다. 이 경우에는 "이중 무료"라는 문제가 있음이 분명합니다. 다음 코드

mySolverVec.push_back(ODESolver(myODEVec[0])); 

에서 일부 메모리를 할당하고 멤버 변수 d_step_ptrd_evolve_ptr에 할당 임시 ODESolver 개체를 만듭니다. 객체는 memcpy (비트 복사)을 벡터에 복사하는 기본 복사 생성자로 복사됩니다. 임시 개체가 파괴되고 메모리가 해제됩니다. 벡터 mySolverVec이 범위를 벗어나면 내부의 모든 객체가 삭제됩니다. 어느 것이 동일한 기억을 다시 해방하려고 시도하고 당신은 거의 충돌이있을 것입니다!

개체의 복사를 금지해야합니다. C++ 11에서는 move와 no copies만을 허용 할 수 있습니다. 오래된 표준을 고수해야한다면 몇 가지 참조 계산 방식이 적합 할 것입니다. boost 라이브러리와 특히 boost::shared_ptr을 살펴보십시오.