Рейтинг:
2
Rick York
Я обнаружил, что да, вам действительно нужно вручную удалять векторы указателей. Если вы используете Visual Studio и макрос DEBUG_NEW, то в противном случае вы увидите утечки памяти в отладчике. По крайней мере, я так думаю. Некоторое время назад я придумал эту маленькую шаблонную функцию, чтобы помочь в этой ситуации :
// delete a vector of objects created with new
template< typename T >
void DeleteVector( std::vector<T> & v )
{
size_t count = v.size();
for( size_t n = 0; n < count; ++n )
delete( v[n] );
v.clear(); // just to be sure
}
Если вы используете вариант malloc для выделения указателей, то вы можете сделать вариацию этой функции, которая вызывает free вместо delete, и поскольку free не является типизированной операцией, функция не должна быть шаблоном.
[no name]
Я обязательно хорошенько в этом разберусь. Было бы хорошей идеей, чтобы все мои классы включали a .h с #define new DEBUG_NEW внутри, чтобы я мог собрать все варианты использования " new " во всем проекте? Я чувствую, что это дало бы мне хорошее представление об утечках памяти, где бы они ни находились.
Я читал, что std::vector::clear() уничтожает и удаляет каждый элемент в векторе, поэтому я считаю, что простого вызова clear() без цикла будет достаточно
jeron1
"Я читал, что std::vector::clear() уничтожает и удаляет каждый элемент в векторе,"
Это, вероятно, относится к памяти, которую выделяет сам вектор (4 или 8 байт, необходимых для хранения ваших указателей), а не к объектам, на которые эти указатели указывают.
[no name]
Откуда cplusplus.com: "удаляет все элементы из вектора (которые уничтожаются), оставляя контейнер размером 0."
jeron1
Элементы в вашем векторе являются указателями. Каждая запись размером 4 или 8 байт удаляется/уничтожается, а не объекты, на которые они ссылаются. Возможно, установите точку останова деструктора на "элементе" и посмотрите, будет ли он вызван, когда ваш вектор будет уничтожен.
[no name]
Отличная идея, я об этом не подумал. На самом деле я использую Unreal Engine 4, который использует Visual Studio для разработки, поэтому я не верю, что есть способ установить точки останова, но я определенно могу вывести что-то на консоль внутри деструктора
jeron1
Никаких точек останова или возможности пошагового просмотра кода? Он должен быть где-то там, я не могу себе представить (и не рассматривал бы) никакого развития без него.
[no name]
Это очень недружелюбный двигатель. Кривая обучения наверняка оттолкнет большинство людей еще до того, как они начнут. Я дошел до того, что разозлился на его бесполезность, отсутствие примеров C++ с документацией или даже четкого объяснения, а также на то, что они, похоже, заботятся только об элементе blueprint, полностью игнорируя тех, кто хочет лучше контролировать и программировать на C++. Все очень сложно, у вас даже не может быть конструкторов с аргументами.
Задайте общий вопрос в google относительно unreal engine, и вы увидите почти только примеры чертежей.
Путь UE4-это единственный путь, в котором нет места привычкам каждого разработчика.
jeron1
Звучит не очень весело.
Рейтинг:
1
CPallini
Используйте умный указатель. Попробуйте, например
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class F
{
int f;
public:
F(int f):f(f) { cout<< "F(" << f << ") ctor called\n";}
~F() { cout << "F(" << f << ") dtor called\n";}
};
int main()
{
vector< F * > v;
v.push_back(new F(1));
vector < unique_ptr< F > > w;
w.push_back( make_unique< F >(2) );
}
Выход:
F(1) ctor called
F(2) ctor called
F(2) dtor called
Рейтинг:
0
KarstenK
Эмпирическое правило состоит в том, что тот, кто создает память, должен ее удалить. Поэтому, когда вы удаляете вектор, вы должны удалить память.
Но у вас есть дополнительная проблема, что ваш вектор может быть скопирован или назначен где-то глубоко в реализации вектора, и поэтому у вас может быть 2 вектора с одной и той же памятью. Может быть, это поможет перезаписать эти операторы, в которых вы копируете память вектора источника.
Я думаю, что вам не нужно выделять элемент с новым, но вы можете использовать типизированный вектор.
std::vector<Item> myList;
[no name]
Итак, в PlayerInventory у меня есть переменная-член std::vector<Item*> items.
Когда PlayerInventory будет уничтожен, элементы также будут автоматически удалены. Однако означает ли это, что память этих элементов все еще выделена и должна быть удалена в деструкторе?
jeron1
"в PlayerInventory у меня есть переменная-член std::vector<Item*> items...."
"Когда PlayerInventory будет уничтожен, элементы также будут автоматически удалены."
Кто-нибудь поправит меня, если я ошибаюсь, но мне это не кажется правильным. Я думаю, что если вы собираетесь "новые" объекты, вам нужно "удалить" их, вероятно, в деструкторе PlayInventory. Я согласен с Карстенком в этом вопросе в использовании типизированного вектора, тогда управление памятью находится вне ваших рук.
[no name]
Мне сказали, что переменные-члены, сам std::vector, будут удалены, когда класс будет уничтожен. Я не знаю, автоматически ли это удаляет указатели в векторе или нет, которые создаются с помощью "new".
вектор объявляется как таковой;
public:
std::vector<Item*> items;
KarstenK
В C++ указатель werent не удалялся при удалении контейнера. Это происходит только с умными указателями.
Совет опытного разработчика: изучите и поймите методы, которые вы хотите использовать ;-)
[no name]
Я лучше всего понимаю, когда пытаюсь, вместо того чтобы читать книгу и не иметь ни малейшего представления о том, что на самом деле переводится в реальном проекте.