清除并重新填充 std::vector<std::vector<T>>导致分配问题



我将数据存储在双std::vector结构中,需要能够重复填充和清除:这导致了一些我不理解的分配问题。

我使用的是结构vector<Coefficients *> XSims,其中Coefficients采用形式

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

我使用以下迭代器绕过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()};}

我很难将这两个功能组合使用如下:

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

我想在循环中运行两个函数:在用初始Coeffiecient*初始化XSims(它永远不会被清除)后,我运行

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

前两个函数运行良好,但第二个Simulate()在运行时崩溃。基本上,它似乎不想在第二个外循环上push_backXsimsIteration:我得到了奇怪的输出:

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

第二个Number of simulations stored in X实际上应该与第一个相同,即1000。

您的末端测试不正确

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

如果您有普通的C/C++数组,这种测试会起作用,但不需要使用容器。测试应该是Xit != XSims.end(),而不是<,所以它应该读取

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

Coefficients::not_end()也是如此。

看看这个:

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();

我看到您为XSims保留了一些内存。然后你调用XStart(),它执行XSims.begin()。你调用的是一个成员函数begin,它在一个零元素的向量上。这对我来说就像是一个危险信号。既然你在公共领域发布了你的代码,我忍不住要批评它。你似乎混淆了一些非常简单的操作,比如递增一个interator。开始、结束以及向前和向后移动的调用已经非常简单了。你所做的只是让你的程序变得难以阅读。

然后,您将使用无效的迭代器来调用不存在的Coefficients对象上的函数。只有在后面的for循环之后,你才能真正把一些东西放入向量中。

在将任何元素放入XSims向量之前,将执行以下几行代码。

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

为了将来参考,我强烈建议您发布一个可编译的示例。在这个过程中,您通常会学到很多东西,而且在这样做和调试时,通常会发现自己的问题。在这种情况下,必须假设在实际的可执行程序中可能正在做什么或可能没有做什么。

如果我从后面而不是从前面清除XSims,它会起作用,我想它会抛出所有东西,包括我想要保留的初始值。

相关内容

最新更新