2013-12-12 3 views
0

Я хранил данные в двойной структуре std::vector, которые мне нужно уметь заполнять и очищать повторно: это вызывает некоторые проблемы с распределением I не понимаю.Очистка и заправка std :: vector <std :: vector <T>> вызывает проблемы с распределением

Я использую структуру 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(); 
} 

Я хочу, чтобы запустить две функции цикла: После инициализации XSims с начальным Coeffiecient* (который никогда не будет очищен), я бегу

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

Первые две функции работают нормально, но второй Simulate() аварии в RUN- время. В основном, это, похоже, не хотят push_backXsimsIteration на втором внешнем контуре: Я получаю странный вывод:

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

Второй Number of simulations stored in X на самом деле должна быть такой же, как первый, то есть 1000.

+0

Почему вы хотите удалить вектор? Он пуст, там ничего нет. 'XW_clear' делает' X_next', и поэтому вы указываете на пустое пространство, так как я не вижу никакого кода, который выделяет что-нибудь там ... –

+0

Нет, он очищает подвектор. 'X_next' переходит к следующему подвэктору. В 'XW_clear' нет проблем, он находится в' Simulate', который выполняет выделение. – Plamen

+0

Я только что понял, я отредактировал фактический доступ, где, похоже, проблема заключается в том, чтобы держать представление коротким! Внутри второго цикла 'Simulate' есть доступ через' Xit'. Я вложу его! – Plamen

ответ

0

Это сработало, если я очистил XSims со спины, а не спереди, я предполагаю, что он выбрасывал все, включая начальное значение, которое я хотел сохранить.

0

Ваш тест на конец не является правильным

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

+0

У меня это было, но по какой-то причине это не сработало ... Я еще раз проверю и дам вам знать, почему! В то же время я нашел еще один ответ. Я изменил направление цикла в 'XW_clear()', чтобы вернуться назад с конца, а 'pop_back '- векторы, которые я хотел обновить. Я думаю, что критерии «X_not_end» в любом случае ошибочны, потому что он очистил все, и я хотел сохранить первый «вектор» в «XSims». – Plamen

0

Взглянув на это:

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(). Вы вызываете функцию-член, начинающуюся с вектора с нулевыми элементами. Мне кажется, что это красный флаг. Поскольку вы разместили свой код в общедоступном домене, я не могу не критиковать его. Кажется, что вы запутываете некоторые очень простые операции, такие как увеличение декрементирующего интернатора. Звонки на начало, конец и движение вперед и назад уже очень просты. Все, что вы сделали, это сделать вашу программу трудной для чтения.

Тогда вы будете использовать этот итератор, который недействителен для вызова функции на несуществующем объекте Coeffecients. Только после цикла for, который приходит позже, вы фактически помещаете что-то в вектор.

Выполняются следующие строки кода, прежде чем вы поместите какие-либо элементы в вектор XSims.

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

В будущем, я настоятельно рекомендую опубликовать компилируемый пример.Во время процесса вы, как правило, много узнаете, и часто вы обнаружите свою собственную проблему при этом и отладке. В этом случае нужно принять много вещей о том, что вы могли бы или не могли сделать в реальной исполняемой программе.

+0

Спасибо за ваши комментарии. Дополнительные операции с итераторами позволяют изменить реализацию stl, проект, который я имею в виду в ближайшем будущем. Что касается функции 'Xstart()', я упоминал в тексте, что, фактически, XSims уже инициирован, поэтому это не вызывает проблемы. На самом деле, я нашел решение, это относительно просто :) – Plamen

+0

То, что вы говорите и показываете нам, несовместимо тогда. В опубликованном примере нет места, где XSims заполняется элементами до пользователя итераторов. – shawn1874

Смежные вопросы