Как очистить вектор указателей c
стереть вектор () и очистить () в C ++
Векторы аналогичны динамическим массивам с возможностью автоматического изменения размера при вставке или удалении элемента, при этом их хранение автоматически обрабатывается контейнером.
вектор :: ясно ()
Функция clear () используется для удаления всех элементов векторного контейнера, что делает его размером 0.
Синтаксис:
Ошибки и исключения
1. Не имеет исключительной гарантии.
2. Показывает ошибку при передаче параметра.
// Программа CPP для иллюстрации
// Реализация функции clear ()
#include
#include
using namespace std;
vector int > myvector;
// Вектор становится 1, 2, 3, 4, 5
// вектор становится пустым
Сложность времени: O (N)
Все элементы уничтожены один за другим.
вектор :: Стирание ()
Функция erase () используется для удаления элементов из контейнера из указанной позиции или диапазона.
Синтаксис:
Ошибки и исключения
1. У него нет гарантии броска без исключения, если позиция действительна.
2. Показывает неопределенное поведение в противном случае.
Извлечение элемента из определенной позиции
// Программа CPP для иллюстрации
// работа функции erase ()
#include
#include
using namespace std;
vector int > myvector< 1, 2, 3, 4, 5 >;
vector int >::iterator it;
Удаление элементов в пределах диапазона
// Программа CPP для иллюстрации
// Реализация функции erase ()
#include
#include
using namespace std;
vector int > myvector< 1, 2, 3, 4, 5 >;
vector int >::iterator it1, it2;
заявка
Получив список целых чисел, удалите все четные элементы из вектора и напечатайте вектор.
Алгоритм
1. Запустите цикл до размера вектора.
2. Проверьте, делится ли элемент в каждой позиции на 2, если да, удалите элемент и уменьшите итератор.
3. Напечатайте окончательный вектор.
// Программа CPP для иллюстрации
// Применение функции erase ()
#include
#include
using namespace std;
Сложность времени: O (N) в худшем случае, когда 1-й элемент удаляется, а O (1) в лучшем случае, когда последний элемент удаляется.
clear () против erase (), когда использовать что?
clear () удаляет все элементы из векторного контейнера, таким образом, его размер равен 0. Все элементы вектора удаляются с помощью функции clear ().
Функция erase (), с другой стороны, используется для удаления определенных элементов из контейнера или ряда элементов из контейнера, тем самым уменьшая его размер на количество удаленных элементов.
Как уничтожить вектор указателей в с ++?
У меня есть следующий код в одном из моих методов:
Должен ли я уничтожить указатели a и b перед выходом из метода?
Или я должен как-то просто уничтожить вектор единиц указателей?
Это еще один интересный случай:
Как насчет этого дела? Теперь мне не нужно ни удалять, ни умные указатели.
Решение
В качестве альтернативы, вы можете использовать std::shared_ptr сделать это за вас, если у вас есть C ++ 11.
И вы просто используете вектор почти так же, как раньше, но не беспокоясь об утечках памяти, когда функция существует. Я говорю почти, потому что вам нужно будет использовать std::make_shared назначить в векторе.
Другие решения
Вам нужно перебрать вектор и delete каждый указатель он содержит. Удаление вектора приведет к утечкам памяти, так как объекты, на которые указывают его элементы, не удален.
TL; DR: объекты остаются, указатели теряются == утечка памяти.
Довольно старомодное решение, которое работает со всеми компиляторами:
В C ++ 11 это становится так просто, как:
Ваш второй пример не требует освобождения указателя; на самом деле это будет плохой ошибкой. Однако это требует осторожности в обеспечении того, чтобы a а также b оставаться в силе по крайней мере до тех пор, пока units делает. По этой причине я бы посоветовал против такого подхода.
Да, вы должны уничтожить эти указатели (при условии, что вы не возвращаете вектор в другом месте).
Вы можете легко сделать это с помощью std :: for_each следующим образом:
Вы не должны удалять, если эти две ситуации совпадают.
В других ситуациях вы должны удалить память, указанную указателями в векторе. в противном случае после удаления указателей невозможно ссылаться на эти области памяти, и это вызывает утечку памяти.
Я бы предложил использовать SmartPointers в векторе. Использование умных указателей — лучшая практика, чем использование сырых указателей. Вы должны использовать умные указатели std :: unique_ptr, std :: shared_ptr или std :: weak_ptr или их эквиваленты повышения, если у вас нет C ++ 11. Вот документация библиотеки поддержки для этих умных указателей.
В контексте этого вопроса, да, вы должны удалить указатели, которые добавляются к вектору. В противном случае это приведет к утечке памяти.
Вы должны удалить их, если у вас не возникнет утечка памяти, в следующем коде, если я прокомментирую две строки удаления, которые деструкторы никогда не вызывали, также вы должны объявить деструктор класса Base как виртуальный. Как уже упоминалось, лучше использовать умные указатели.
Вывод с не виртуальным базовым деструктором (утечка памяти):
И да и нет. Вам не нужно удалять их внутри функция, но по другим причинам, чем вы могли подумать.
По сути, вы передаете права собственности на объекты вектору, но вектор об этом не знает, и поэтому не будет автоматически удалять указатели. Так если Вы храните необработанные указатели в векторе, вы должны вручную вызывать delete для них некоторое время. Но:
И кроме того: Не используйте простой новый. Используйте умные указатели. Независимо от того, что вы делаете с ними, умные указатели позаботятся о правильном уничтожении содержащихся объектов. Не нужно использовать новый, не нужно использовать удаление. Когда-либо. (За исключением случаев, когда вы пишете свои собственные низкоуровневые структуры данных, например, умные указатели). Так что если вы хотите иметь вектор, полный владеющих указателей, это должны быть умные указатели. Таким образом, вам не придется беспокоиться о том, когда и как уничтожать объекты и освобождать память.
Как правильно освободить память занятую элементами vector
Не могли бы пожалуйста подсказать, при добавление элемента в вектор я создаю его с помощью команды new
И в конце программы я хочу чтобы деструктор класса, который хранит в себе vector удалил все его элементы, и если честно не получается, может кто подскажет?
4 ответа 4
Вот демонстрационная программа.
Ее вывод на консоль
Если хотите использовать цикл вместо алгоритма, то достаточно написать
Результат будет такой же, что и для программы, показанной выше.
Что касается вашего собственного цикла, то правильно его будет записать следующим образом:
Обратите внимание, что вместо данного объявления конструктора
будет лучше записать
Также в виду того, что вы используете вектор указателей, вам следует либо запретить копирование объектов класса, как, например, в определении класса записать
Либо определить их явно.
Company()’: Company.h:26:13: error: ‘default_delete’ is not a member of ‘std’ std::default_delete (); ^ Company.h:26:38: error: expected primary-expression before ‘>’ token std::default_delete (); ^ Company.h:26:40: error: expected primary-expression before ‘)’ token std::default_delete ();
Если вы хотите чтобы при удалении элементов автоматически выполнялся их деструктор, то вам нужно либо завернуть указатели в «умные указатели», либо хранить в векторе не указатели, а сами объекты.
Второй вариант, деструктор вектора автоматически вызовет деструкторы для каждого элемента:
Вам нужно просто в цикле сделать
Однако имейте в виду, что если с вектором такой номер еще пройдет, то вот с другим типом контейнера запросто могут возникнуть проблемы.
В том числе именно по этой причине имеет смысл использовать «умные указатели» для хранения указателей в контейнерах.
Как очистить вектор из C++ из памяти
Я новичок в C++, поэтому это может быть вопрос новичков, но я не совсем понимаю, как очистить его от памяти. Я искал в Интернете и смотрел несколько ответов, но не понял, как правильно выполнить то, что я пытаюсь сделать.
Как я могу правильно очистить свой вектор от памяти в C++? Спасибо, и я извиняюсь, если это дублированный пост.
Как уже упоминалось в комментарии ниже, я хотел бы вернуть использованную память.
за исключением того, что он не возвращает никакой памяти в систему, так как емкость остается неизменной.
Если вы хотите сбросить вы вектор обратно в порожнем состоянии, то мы можем использовать swap трюк, чтобы поменять местами содержимое вектора в временный, который будет разрушаться и освободить память
Это создаст временный пустой вектор, замените его тем, который у вас есть, теперь он пуст, а затем уничтожьте все во временном векторе.
Вы можете видеть, как он работает в этом маленьком примере
Когда ваша программа закончится, vector dtor будет вызван и удалит ваш вектор для вас, поскольку вы выделили его в стеке. Кроме того, dtor для ElementData будет вызываться для каждого в векторе.
std :: векторные переменные обычно удаляются автоматически, когда вы выходите из области видимости, или когда объект класса, из которого они являются членами, уничтожается. Деструктор std :: vector также уничтожает все элементы вектора.
Чтобы полностью очистить вектор в явном виде, сначала очистите вектор (уничтожьте элементы)
затем вернуть память, ранее зарезервированную для векторных элементов
Только вызывайте shrink_to_fit если это вероятно, что вектор ранее содержал гораздо больше элементов, чем вы собираетесь его заполнить.
В большинстве случаев лучший способ – ограничить область действия вектора тем, где он действительно необходим. Итак, вместо чего-то вроде:
Другое преимущество этого заключается в том, что после того, как Elements выйдет из сферы действия, вы не можете его повторно использовать повторно. Если функция мала, вам, вероятно, не нужно создавать новую явную область. Возврат из функции будет иметь тот же эффект.
Elements.clear() будут делать то, что вы хотите.
Вот остальные функции, доступные для векторов.
Каков правильный способ освободить std:: вектор указателей на C++?
Я искал StackOverflow, но не смог найти ответ на этот вопрос.
не делает ли это недействительным вектор при каждом удалении? Я в полном замешательстве.
10 ответов
не влияет на итератор. Он не изменяет итератор, не делает итератор недействительным или удалить указатель ссылается итератор из коллекции. Все это делает свободная память, что указатель ссылается итератор указывает на. Указатель должен быть удален из коллекции по отдельности.
делает именно то, что вам нужно, без необходимости повторять и удалять содержимое std::vector
другой способ C++ сделать это-определить вспомогательную структуру:
а затем используйте алгоритмы:
В общем в C++ вы должны скрыть управление памятью как можно больше, чтобы избежать ошибок памяти. Если вы не делаете много копирования указателей и не заботитесь о производительности, я бы просто использовал shared_ptr.
Он является частью стандарта TR1 и доступен в большинстве современных компиляторов C++ из коробки (http://anteru.net/2008/09/01/260/) и больш для пожара и забывает управление памяти.
вероятно, вы должны использовать какой-то управляемый указатель, скорее всего, общий указатель.
Если вы удалите вектор, пока кто-то еще держится за один из этих указателей, вы получите очень неприятное поведение, если они попытаются разыграть его. Общий указатель избавит вас от головной боли.
Если вы можете гарантировать, что ничто другое не будет ссылаться на указатели после удаления вектора, вы все равно можете использовать автоматический указатель. Он будет управлять освобождением для вас, когда вектор будет уничтожен. Накладные расходы минимальны, и это делает вашу жизнь намного проще.
все в порядке. Удалении *i (объект, на который указывает элемент вектора), а не i (элемент вектора), поэтому вектор не является недействительным.
посмотреть этот вопрос для случая, когда разработчик также хотел удалить все i s, и для решения для него ( vector_day.clear() ) после цикла.
вот удобный класс, который я написал некоторое время назад, имея дело с той же проблемой. Я преобразовывал некоторый код из старых векторов и списков на основе RogueWave в векторы и списки на основе STL и нуждался в некотором способе эмуляции метода clearAndDestroy() RW для списков указателей. Метод clearAndDestroy () можно переопределить для обработки различных типов структур (я включил только вектор здесь для краткости).
другой способ итерации + удаления-использовать while(!empty) петли. Преимущество этого метода заключается в том, что элемент сначала удаляется из контейнера, удаляются послесловия. Это безопасно для любого контейнера:
