Управление памятью и C ++ контейнерные классы - PullRequest
0 голосов
/ 01 марта 2012

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

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

Спасибо!

Ответы [ 4 ]

3 голосов
/ 01 марта 2012

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

Последний.

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

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

2 голосов
/ 01 марта 2012

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

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

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

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

1 голос
/ 01 марта 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();
0 голосов
/ 01 марта 2012

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

...