Я использую вектор с моим собственным типом класса:
std::vector<CItem> m_vItems;
В моем классе я инициализирую SFML-типы, такие как текстура и спрайт:
class CItem
{
(...)
sf::Texture m_Texture;
sf::Sprite m_Sprite;
sf::IntRect* m_pRect;
(...)
}
Я пытаюсь передать объект моему вектору, объявленному как член другого класса CLevel
и я делаю это внутри метода этого класса следующим образом:
CItem *temp = new CItem(x, y, kind);
m_vItems.push_back(*temp);
Как видите, я не удаляю temp
указатель с delete
, но в деструкторе класса CLevel
У меня есть простая строка:
std::vector<CItem>().swap(m_vItems);
И меня немного смущают утечки памяти. Есть ли в моей программе некоторые из них или строка выше для решения проблемы, и мой пример написан правильно?
CItem *temp = new CItem(x, y, kind);
m_vItems.push_back(*temp); // here a copy of *temp is pushed into vector
Вы должны вызвать delete где-нибудь, чтобы удалить то, что вы выделили с помощью temp:
delete temp;
чтобы избежать утечки памяти. Любой звонок в new
должен иметь соответствующий вызов delete
где-то. Это не влияет на копию temp, которая была помещена в вектор. Он все еще существует, пока существует вектор.
Лучше всего использовать только:
m_vItems.push_back(CItem(x, y, kind)); // implement this constructor correctly
// to avoid uninitialized variables
Всегда, когда возникают утечки, вы можете профилировать свою программу с помощью инструмента: Valgrind или Visual Leak Detector.
Ваша программа звонит new
без соответствия delete
и это не прошло результат new
в другой класс, который будет управлять этим для вас. Поэтому ваша программа имеет утечку памяти.
У вас есть проблемы с использованием m_vItems.push_back(CItem(x, y, kind));
вместо двухстрочного примера, который вы дали?
если вы работаете на платформе Windows, вы можете использовать библиотеку CRT, чтобы определить наличие утечек в определенном разделе кода. это ссылка на сайт объясняет, как сделать это в VS 2012, это также доступно для более ранних версий.
Предполагая, что вам нужно сохранить вектор указателей, а не вектор CItems, я бы использовал умный указатель для управления временем жизни объекта. shared_ptr прост в использовании:
shared_ptr<CItem*> temp(new CItem(x,y,z));
m_vItems.push_back(temp);
Когда вектор уйдет, CItem будет очищен правильно. Когда элементы передаются, они также будут обрабатываться правильно — без утечек памяти.
Утечка памяти — это когда пространство выделяется в куче (в вашем случае, вызывая new), и ссылка на эту память теряется. Другими словами, у вас нет возможности восстановить память, вызвав delete. Если вы используете swap для перемещения указателей от одного вектора к другому, то технически это не утечка, потому что у вас все еще есть ссылка на память в другом векторе, и вы все равно можете вызвать delete.
Не забудьте позвонить удалить в конце концов. В некоторых случаях может быть заманчиво, в зависимости от использования, просто позволить очистить систему позже и не удалять память никогда, например. если код является CGI. Однако это может вызвать проблемы позже, когда код используется в случае использования, который изначально не предполагался, например модульный тест, который вызывается из долгосрочной структуры. Как правило, стоит потратить время на кодирование удаления, даже если это не имеет отношения к непосредственной цели, вместо того, чтобы поставить себя в положение, в котором вам, возможно, придется вернуться назад и попытаться исправить это позже.