Будут ли удаляться динамически размещенные указатели объектов при заполнении std :: vector по значению?

Возможный дубликат:
Почему использование «нового» вызывает утечки памяти?

Я довольно новичок в STL, и я читал, что хорошей практикой является сохранение векторов объектов, а не векторов указателей на объекты. В попытке выполнить это кредо я столкнулся со следующим сценарием:

//Approach A
//dynamically allocates mem for DD_DungeonRoom object, returns a pointer to the block.
//then, presumably, copy-constructs the de-referenced DD_DungeonRoom as a
//disparate DD_DungeonRoom object to be stored at the tail of the vector
//Probably causes memory leak due to the dynamically allocated mem block not being
//caught and explicitly deleted
mvLayoutArray.push_back(*(new DD_DungeonRoom()));

//Approach B
//same as A, but implemented in such a way that the dynamically allocated mem block
//tempRoom can be deleted after it is de-referenced and a disparate DD_DungeonRoom is
//copy-constructed into the vector
//obviously rather wasteful but should produce the vector of object values we want
DD_DungeonRoom* tempRoom = new DD_DungeonRoom();
mvLayoutArray.push_back(*(tempRoom));
delete tempRoom;

Первый вопрос: в подходе А возникает утечка памяти?
Второй вопрос: если предположить, что A вызывает утечку памяти, B решает ее?
Третий вопрос: есть ли (или, более вероятно, «что есть») лучший способ добавления пользовательских объектов класса (например, требующих динамического выделения через «new» или «malloc») в вектор по значению?

Спасибо,
CCJ

2

Решение

Первый вопрос: в подходе А возникает утечка памяти?

Да.

Второй вопрос: если предположить, что A вызывает утечку памяти, B решает ее?

Да, но это глупое решение. И небезопасно в том случае, если DD_DungeonRoomКопировать конструктор или vector::push_back бросает исключение.

Третий вопрос: есть ли (или, скорее, «что есть») лучший способ
добавить пользовательские объекты класса (например, требующие динамического выделения через «новый»
или ‘malloc’) к вектору по значению?

Никакие объекты в C ++ не требуют динамического выделения памяти. Просто добавьте объекты непосредственно в вектор, вызывающий конструктор, без new,

mvLayoutArray.push_back(DD_DungeonRoom());

Еще лучше, если ваш компилятор поддерживает эту функцию (она является новой для C ++ 11), будет использовать emplace_back который полностью обходит любые копии, и создает ваш объект непосредственно в векторе. Просто передайте те же аргументы, что и вашему конструктору. В нашем случае это не так:

myLayoutArray.emplace_back();
8

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

Подход А вызывает утечку, да.
Подход B этого не делает, но поскольку все, что вы делаете, это выделяете объект в куче, помещаете копию в вектор, а затем удаляете ее, в этом случае вы можете сделать то же самое:

DD_DungeonRoom tempRoom;
mvLayoutArray.push_back(tempRoom);

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

Кроме того, если вам любопытно, если что-то вытечет из памяти, есть много хороших инструментов, которые действительно могут попробовать и посмотреть, что произойдет. Valgrind это один из примеров, который очень прост в использовании.

2

если ваша единственная проблема с aproch A — утечка памяти, почему бы не использовать вектор shared_ptr?

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