Вопрос

I store the data in a double std::vector structure, which I need to be able to fill and clear repeatedly: this is causing some allocation issues I don't understand.

I am using a structure vector<Coefficients *> XSims, where Coefficients takes the form

class Coefficients{
int N;
 public:
vector<gsl_vector *> Coefs;
//Iterator to traverse the vector structure.
vector<gsl_vector*>::iterator it;
void it_start(){
    it = Coefs.begin();
}
void it_end(){
    it = Coefs.end();
}
void it_next(){
    ++it;
}
void it_prev(){
    --it;
}
bool not_end(){
    return it < Coefs.end();
}
    //Return number of vectors contained.
size_t length(){return Coefs.size();}

//Append pointer to outside data into the Coefs structure.
void append( gsl_vector * X ){
    Coefs.push_back(X);
}

Coefficients(int N1) : N(N1) {
    Coefs.reserve(N);
}
    //Clean up procedure
void Clear(){
    //Forward iterator.
    it_start();
    while(not_end()){
        gsl_vector_free((*it));
        it_next();
    }
    Coefs.clear();
}

~Coefficients(){
    //Forward iterator.
    Clear();
    Coefficients::Coefs.clear();
}
 };

I use the following iterator to get around XSim:

    vector<Coefficients *>::iterator Xit;
inline void Xstart(){Xit = XSims.begin();}
inline void Xend(){Xit = XSims.end();}
inline void X_next(){++Xit;}
inline void X_previous(){--Xit;}
inline bool X_not_end(){return {Xit < XSims.end()};}

The two functions I'm struggling to use in combination are as follows:

inline void Simulate(){
    XSims.reserve(N+1);
    Xstart();

    for(int i=0;i<N; i++){
        //Build a container to insert into XSims
        Coefficients * XsimsIteration = new Coefficients(1000);
        // time points to previous vector of simulations.

        (*Xit)->it_start();

        for(int m=0;m<1000;m++){
            //Allocate free space for the components of the DW and Xsims.
            gsl_vector * X = gsl_vector_alloc(X0.X0->size);
            XsimsIteration->append(X);

                   gsl_vector_memcpy(X,(*Xit));

            //Next simulation
            (*Xit)->it_next();
        }
        cout << "Number of sims being inserted into X = " << XsimsIteration->length() << endl;
        //Insert XsimsIteration into the XSims container
        XSims.push_back(XsimsIteration);


        //next time point
        X_next();
        cout << "Number of simulations stored in X = " << (*Xit)->length() << endl;
    }
}

inline void XW_clear(){
    Xstart();
    //Don't want to clear the initial values, so step forward!
    X_next();
    while(X_not_end()){
        (*Xit)->Clear();
        X_next();
    }
    XSims.clear();
}

I want to run the two functions in loop: After initializing the XSims with an initial Coeffiecient* (which never gets cleared), I run

Simulate();
XW_clear();
Simulate();

The first two functions work fine, but the second Simulate() crashes in run-time. Basically, it seems not to want to push_back the XsimsIteration on the second outer-loop: I get the strange output:

Number of sims being inserted into X = 1000
Number of simulations stored in X = 0

The second Number of simulations stored in X should in fact be the same as the first, i.e. 1000.

Это было полезно?

Решение 3

It worked if I cleared the XSims from the back rather than from the front, I guess it was throwing out everything including the initial value that I wanted to keep.

Другие советы

Your test for the end is not correct

inline bool X_not_end(){return {Xit < XSims.end()};}

This kind of test will work, if you have plain C/C++ arrays, but it need not work with containers. The test should be Xit != XSims.end(), not <, so it should read

inline bool X_not_end(){return Xit != XSims.end();}

Same goes for Coefficients::not_end().

Taking a look at this:

inline void Simulate(){
    XSims.reserve(N+1);
    Xstart();

    for(int i=0;i<N; i++){
        //Build a container to insert into XSims
        Coefficients * XsimsIteration = new Coefficients(1000);
        // time points to previous vector of simulations.

        (*Xit)->it_start();

I see that you have reserved some memory for XSims. Then you call XStart() which executes XSims.begin(). You are calling a member function begin on a vector with zero elements. That seems like a red flag to me right there. Since you posted your code on a public domain, I can't help but critique it. It seems like you are obfuscating some very simple operations such as incrementing a decrementing an interator. The calls to begin, end, and moving forward and backward are already very simple. All that you have done is to make your program difficult to read.

Then you will use that iterator which is not valid to call a function on a nonexisting Coeffecients object. Only after the for loop which comes later do you actually put something into the vector.

The following lines of code are being executed before you put any elements into the XSims vector.

(*Xit)->it_start();
(*Xit)->it_next(); // why is this in the for loop?  You are iterating over an empty vector

For future reference, I highly recommend that you post a compilable example. You will typically learn a lot during the process, and often one will find their own problem while doing so and debugging. In this case one has to assume many things about what you might or might not be doing in the actual executable program.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top