Должен ли я удалить вектор <string>?
Я очень многому научился в последние несколько дней о программировании на С++.
Мне это нравится:)
Я знаю, что я должен освободить память - теперь в моем мире существуют золотые правила "каждый malloc = free" или "каждый новый = удалить", но я использую их для простых объектов.
Что относительно вектора? Где бы я ни был, я использую vector.clear(), но этого явно недостаточно, потому что у меня огромные утечки памяти.
Не могли бы вы посоветовать мне, как я должен лечить эту вещь?
* Редактирование
Спасибо, ваши комментарии заставляют меня задуматься об альгорифме этого приложения, и я полностью удалю вектор.: O
Извините, я начал объяснять, что здесь используется, и я узнал, что мне действительно нужно. Это так, когда вы кодируете последние 3 дня в течение 18 часов в день: |
* Редактировать 2
Это безумие. Небольшими изменениями в коде, я избавился от использования памяти от 2x130 мб (постоянно растет) до 2x 13,5 МБ, постоянного размера. Спасибо, что задумался об этом по-другому.
Btw. такой обзор самообъявления получил имя - кто-нибудь помнит это? Это когда вы спрашиваете кого-нибудь (даже свою мать или собаку) и начинаете объяснять, в чем ваша проблема, и вдруг вы решаете эту 5-часовую проблему самостоятельно, просто пытаясь взглянуть на нее с другой точки зрения или просто попытавшись подытожить то, что она все о. Я часто нахожу, что меня улавливают...
Ответы
Ответ 1
Правило заключается в том, что при очистке вектора объектов вызывается деструктор каждого элемента. С другой стороны, если у вас есть вектор указателей, vector::clear()
не будет называть delete
на них, и вы должны сами их удалить.
Итак, если все, что у вас есть, это вектор строк, а не указатели на строки, то утечка памяти должна быть вызвана чем-то другим.
Ответ 2
Вызов v.clear()
уничтожит все объекты, которые в настоящее время хранятся внутри v
, но он не освободит память (предполагается, что вектор скоро будет заполнен снова).
Если вы действительно хотите освободить память, идиома
vector<string>().swap(v);
Это создаст новый (временный) вектор и заменит его содержимое на v
. Затем временный вектор уничтожается, освобождая память вместе с ней.
Ответ 3
Вам не нужно это делать. std::string очищает себя, поэтому строки не являются вашей проблемой. Помните, что вы не использовали new
, поэтому вам не нужно использовать delete
.
Вероятно, вам следует узнать о RAII - это значительно упрощает выделение и освобождение. Вы избегаете утечек памяти таким образом.
Ответ 4
Удаление элементов из контейнеров STL гарантированно вызывает деструкторы этих элементов.
Однако, если у вас есть контейнер с некоторым типом pointer-to-T
, вам все равно придется освобождать выделенную память самостоятельно (в этом случае вызывается "деструктор" для указателя, который не работает).
Если вы не хотите вручную управлять памятью в этом случае, рассмотрите возможность использования умного указателя или контейнер указателей.
Ответ 5
Вектор (как и все стандартные контейнеры) владеет объектами внутри него.
Поэтому он несет ответственность за их уничтожение.
Примечание. Если вектор содержит указатели, то он имеет указатели (не то, что указатели указывают на). Поэтому их нужно удалить. Но есть более простые способы.
Вы можете использовать вектор интеллектуальных указателей. На самом деле вы должны использовать какую-то форму умного указателя почти для всего. Если вы используете указатели, вы, вероятно, все еще программируете, как программист на C.
Итак:
std::vector<int> data; // clear is fine.
std::vector<int*> data1; // Now things need to be deleted.
// alternative 1:
std::vector<boost::shared_ptr<int> > data2; // The shared pointer will auto
// delete the pointer.
// alternative 2:
boost::ptr_vector<int> data3; // Here the container knows that
// it is holding pointers and will
// auto de-reference them when you
// its members.
Но похоже, что вам нужно начать думать о умных указателях.
int* x = new int(5);
// Do stuff.
*x = 8;
delete x;
// --- Instead use a smart pointer:
std::auto_ptr<int> x(new int(5));
// Do stuff.
*x = 8;
// No delete (the auto ptr handles it.
Ответ 6
Если у вас есть вектор и он выходит из области видимости, все объекты в векторе уничтожаются. На самом деле нет необходимости вызывать clear(), если вы не хотите выгружать содержимое и повторно использовать вектор.
Однако, если вы случайно используете что-то вроде вектора, тогда деструктор объектов, на которые указали, не будет вызываться как векторный деструктор, не будет следовать указаниям, указанным указателями.
Все, что сказал, подтвердили ли вы, что у вас есть настоящие утечки памяти и что они вызваны данными в векторе?
Ответ 7
Дайте пример использования. Деструктор на строке вызывается вектором:: clear. Ваша проблема лежит в другом месте моего друга.
также проверьте:
Выполняет ли std::vector.clear() удаление (свободной памяти) для каждого элемента?
Ответ 8
Как предлагается rlbond, используйте RAII.
Хорошее эмпирическое правило никогда не ставит новые и удаляет вызовы в ваш основной поток кода. Всегда старайтесь помещать их в объекты, чтобы деструктор объекта мог освободить то, что нужно освободить. Таким образом, вы избегаете необходимости помнить о вызове delete, и это делает ваш код исключительным безопасным (при условии, что вы делаете исключение операций с объектами безопасным).
Например, если у вас есть вектор указателей на строки STL или массивы символов C-стиля, поместите это в StringContainer (используйте лучшее имя) и у StringContainer есть вектор, а в деструкторе StringContainer выполняется цикл for для удаления каждой строки в векторе.
Вы можете сделать вектор внутри StringContainer открытым членом и запутаться с ним напрямую, но он даже лучше сконструирован, чтобы сделать его приватным или защищенным и добавить некоторые функции-члены для управления вектором строки *.
Таким образом, ваша основная программа на С++ никогда не должна видеть новую или удалять в любом месте. Вместо этого у него должно быть много объектов, выделенных стеком, auto_ptrs и shared_ptrs.