Может ли быть утечка памяти при использовании вектора указателя в c ++? - PullRequest
4 голосов
/ 01 апреля 2010

Я пробовал это:

....
vector<players*> player;
for (int i = 0; i<10; i++)
{
    player.push_back(new players());
}
...

И мне интересно, нужно ли мне освободить память для вектора? Если да, то как?

Ответы [ 3 ]

8 голосов
/ 01 апреля 2010

Если вам нужно хранить указатели на вещи в контейнере, вы должны либо хранить какой-то умный указатель (например, std::tr1::shared_ptr или boost::shared_ptr), либо использовать контейнер, предназначенный для хранения указателей, как те, которые есть в Boost Pointer Container Library .

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

3 голосов
/ 01 апреля 2010

Да, вам нужно delete самостоятельно. Вектор только «разрушает» указатели (которые ничего не делают).

Если можете, используйте библиотеку контейнеров Boost указатель , и вам не придется об этом беспокоиться Однако, если вы не можете, вам нужно обернуть контейнер. Рассмотрим исключение между временем заполнения контейнера и временем удаления его элементов. Вы будете не выполнять код удаления элемента и утечки.

Простая оболочка может выглядеть так:

struct default_deleter
{
    template <typename T>
    void operator()(T* pPtr)
    {
        delete pPtr;
    }

};

template <typename T, typename Deleter = default_deleter>
struct container_wrapper
{
    typedef T container_type;
    typedef Deleter deleter_type;

    container_wrapper(container_type pContainer = container_type()) :
    container(pContainer)
    {}

    ~container_wrapper(void)
    {
         std::for_each(container.begin(), container.end(), deleter_type());
    }

    container_type container;
};

Используйте это как:

typedef std::vector<int*> vec_intptr;
typedef container_wrapper<vec_intptr> vec;

vec v;
v.container.push_back(new int); // and never worry about it again

Это простая оболочка. Любые операции pop_back(), erase() и т. Д. Будут иметь неправильный эффект. Я настоятельно рекомендую использовать Boost.

Можно подумать об использовании контейнера auto_ptr. Наоборот, это плохая идея; семантика копирования auto_ptr не позволяет ему работать. Наилучший вариант - по возможности избавиться от динамического выделения.

2 голосов
/ 01 апреля 2010

поскольку вы создаете новых игроков (), вам придется их удалить. вероятно, лучше всего пройтись по вектору, удалив игроков, а затем очистить свой вектор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...