Управление памятью и контейнерные классы C++

У меня возникли проблемы с использованием стандартных классов контейнеров (список, карта и т. д.) в С++. Проблема, похоже, связана с удалением элементов для контейнеров. Я пытаюсь сохранить указатели на объекты внутри контейнера, а затем, когда я хочу удалить элемент из контейнера, я использую либо erase, либо remove. Когда я это делаю, действительно ли контейнер удаляет объект, который был в контейнере, или просто удаляет указатель из контейнера?

Я надеюсь, что он просто удалит указатель, потому что я использую контейнеры для группировки объектов, а объект может находиться более чем в одной группе, поэтому я не хочу, чтобы он удалялся при удалении из контейнера !

Спасибо!


person James Bedford    schedule 01.03.2012    source источник
comment
Вы можете проверить это сами, поместив код отладки в деструктор элемента, например оператор std::cout. Впрочем, в чем именно состоит некоторая беда?   -  person Mr Lister    schedule 01.03.2012
comment
Спасибо за подсказку с деструктором. Было трудно отследить, в чем проблема, но в конечном итоге она была связана с интерпретацией поврежденных сообщений UDP и случайным сбоем, а не с проблемой управления памятью! Просто хотел убедиться, что я правильно понял классы контейнеров С++. Спасибо!   -  person James Bedford    schedule 10.03.2012


Ответы (4)


Когда я это делаю, действительно ли контейнер удаляет объект, который был в контейнере, или просто удаляет указатель из контейнера?

Последний.

... поэтому я не хочу, чтобы он удалялся при удалении из контейнера!

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

person Fred Foo    schedule 01.03.2012

Когда я это делаю, действительно ли контейнер удаляет объект, который был в контейнере, или просто удаляет указатель из контейнера?

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

Именно здесь на помощь приходит концепция RAII в C++. спасать. Вы можете использовать интеллектуальный указатель вместо необработанных указателей внутри контейнера, и как только вы это сделаете, освобождение будет неявно обрабатываться интеллектуальным указателем вместо того, чтобы у вас возникали накладные расходы на явную обработку управления памятью.

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

person Alok Save    schedule 01.03.2012

Эффективный STL Скотта Мейера даст вам ответ на вопрос о хранении необработанных указателей в классах контейнеров.

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

При распределении, например, std::vector, перед его очисткой вы должны удалить каждый его элемент вручную.

std::vector<int*> v(10;
for (int i=0; i<10; i++)
   v.at(i) = new int;

Неправильный путь

v.clear(); // !!! MEMORY LEAK 

правильный путь

for (int i=0; i<10; i++)
    delete v.at(i);

а потом

v.clear();
person linello    schedule 01.03.2012

компилятор не удаляет объект, помещенный в динамическую память

person triclosan    schedule 01.03.2012