В Rails 5
Student.
find_or_initialize_by(:user_id => current_user.id).
update(:department => 1)
(все отзывы взяты из ответа @Zorayr).
void Population::clearPool( std::vector <Chromosome*> & a )
{
for ( int i = 0; i < a.size(); i++ ) {
delete a[i];
}
a.clear();
}
Обратите внимание, что вектор передается по ссылке. В вашем коде используется копия вектора, что означает, что он не изменился в вызывающей программе. Поскольку вы удаляете указатели в копии, указатели в оригинале теперь недействительны - я подозреваю, что вы используете эти недопустимые указатели каким-то образом, не показанным в опубликованном вами коде.
Поскольку было опубликовано несколько шаблонных решений которые используют алгоритмы библиотеки C ++, вы также можете рассмотреть шаблонное решение, в котором нет:
template <class C> void FreeClear( C & cntr ) {
for ( typename C::iterator it = cntr.begin();
it != cntr.end(); ++it ) {
delete * it;
}
cntr.clear();
}
Используя это, вы можете освободить любой контейнер динамически выделяемых объектов:
vector <Chromosome *> vc;
list <Chromosome *> lc;
// populate & use
FreeClear( lc );
FreeClear( vc );
Немного измененная версия по сравнению с (@ 1800 ИНФОРМАЦИЯ).
struct DeleteFromVector
{
template <class T>
void operator() ( T* ptr) const
{
delete ptr;
}
};
std::for_each(aVec.begin(), aVec.end(), DeleteFromVector());
Я не знаю, почему у вас происходит сбой, но я предполагаю, что одна из возможностей заключается в том, что размер вектора не совпадает с размером, который вы передаете. Также я заметил, что вы повторяя от 0 до размера-2, разве вы не хотите пройти весь путь до конца?
Один из способов удалить все элементы в массиве с помощью идиоматического C ++ - это примерно так:
template<class T>
class deleter
{
public:
void operator()(const T* it) const
{
delete it;
}
};
std::for_each(a.begin(), a.end(), deleter<Chromosome>());
У лямбда-выражения Boost уже есть функтор для удаления последовательностей указателей, кстати:
std::for_each(a.begin(), a.end(), boost::lambda::delete_ptr());
Я обнаружил проблему.
Она была в самом хорошо скрытом (не кем иным, как тупым старым мной) месте, какое только могло быть.
Как некоторые могли догадаться, это программа генетических алгоритмов. Это для учебника, который я делаю. Я выбирал точки кроссовера для хромосом случайным образом из функции колеса рулетки, которую я сделал. Ну ... внутри там было -1, чего там быть не должно. Это разрушило буквально все и в конечном итоге привело к ошибке сегментации.
Спасибо всем за вашу помощь, в этом посте я увидел несколько действительно хороших практик, которым я собираюсь следовать
Вы уверены, что каждый указатель в векторе указывает на другой объект? (т.е. два указателя не указывают на один и тот же объект, который вы пытаетесь удалить дважды.
Вы уверены, что не удалили некоторые указатели перед вызовом этого метода? (т.е. вы уверены, что каждый указатель в списке указывает на действительный объект?)
Наиболее вероятная причина - это вызов delete дважды для одного и того же адреса. Это может произойти, если вы добавили один объект к вектору более одного раза. Чтобы обнаружить эту вставку некоторого оператора, который выведет адрес объекта, вы затем удалите .
printf( "will delete %d\n", (int)c );
delete c;
Я рекомендую использовать интеллектуальный указатель (например: auto_ptr) вместо необработанного указателя и просто использовать метод vector :: clear, который будет вызывать деструктор для каждого элемента
void Population::clearPool(std::vector<Chromosome*>& a)
{
for(size_t i = 0; i < a.size(); i++) {
delete a[i];
}
a.clear();
}
Похоже, что некоторые указатели в вашем коде не ссылаются на правильные объекты хромосомы. Это может произойти, если вы попытаетесь удалить некоторые объекты дважды в результате выполнения кода:
Population p;
vector<Chromosome*> chromosomes;
p.clearPool(chromosomes,chromosomes.size()); // You pass by value, so chromosomes is not changed
p.clearPool(chromosomes,chromosomes.size()); // Delete already deleted objects second time
Вы можете найти полезный ptr_vector в Библиотеке контейнера указателя повышения , чтобы избежать подобных ошибок