Работа с памятью при использовании std :: vector

Я использую вектор с моим собственным типом класса:

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);

И меня немного смущают утечки памяти. Есть ли в моей программе некоторые из них или строка выше для решения проблемы, и мой пример написан правильно?

1

Решение

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.

1

Другие решения

Ваша программа звонит new без соответствия deleteи это не прошло результат new в другой класс, который будет управлять этим для вас. Поэтому ваша программа имеет утечку памяти.

У вас есть проблемы с использованием m_vItems.push_back(CItem(x, y, kind)); вместо двухстрочного примера, который вы дали?

2

если вы работаете на платформе Windows, вы можете использовать библиотеку CRT, чтобы определить наличие утечек в определенном разделе кода. это ссылка на сайт объясняет, как сделать это в VS 2012, это также доступно для более ранних версий.

0

Предполагая, что вам нужно сохранить вектор указателей, а не вектор CItems, я бы использовал умный указатель для управления временем жизни объекта. shared_ptr прост в использовании:

shared_ptr<CItem*> temp(new CItem(x,y,z));
m_vItems.push_back(temp);

Когда вектор уйдет, CItem будет очищен правильно. Когда элементы передаются, они также будут обрабатываться правильно — без утечек памяти.

0

Утечка памяти — это когда пространство выделяется в куче (в вашем случае, вызывая new), и ссылка на эту память теряется. Другими словами, у вас нет возможности восстановить память, вызвав delete. Если вы используете swap для перемещения указателей от одного вектора к другому, то технически это не утечка, потому что у вас все еще есть ссылка на память в другом векторе, и вы все равно можете вызвать delete.

Не забудьте позвонить удалить в конце концов. В некоторых случаях может быть заманчиво, в зависимости от использования, просто позволить очистить систему позже и не удалять память никогда, например. если код является CGI. Однако это может вызвать проблемы позже, когда код используется в случае использования, который изначально не предполагался, например модульный тест, который вызывается из долгосрочной структуры. Как правило, стоит потратить время на кодирование удаления, даже если это не имеет отношения к непосредственной цели, вместо того, чтобы поставить себя в положение, в котором вам, возможно, придется вернуться назад и попытаться исправить это позже.

0
По вопросам рекламы [email protected]