Как удалить объект в наборе - PullRequest
10 голосов
/ 30 апреля 2011

В моей программе на C ++ я создаю объекты в одной функции, используя new. Эти объекты вставляются в набор. Когда я хочу удалить объекты из набора, я использую итератор в цикле for. Когда я удаляю объект из набора, мне все еще нужно удалить объект, чтобы освободить его память, правильно? Я попытался использовать удаление, но затем я получаю сообщение об ошибке, что освобождаемый указатель не был выделен Так как это можно сделать?

Вот код, в котором я создаю объект и затем вставляю его в набор

set <myObject> myobjectlist;
myObject *myobject = new myObject;
myobjectlist.insert(*myobject);

В другой функции я пытаюсь удалить объект из набора и освободить его память:

    for (set<myObject>::iterator i = myobjectlist.begin(); i != myobjectlist.end(); i++)
if (i->myObjectID == myObjectID)
{
    myobjectlist.erase(*i);
    delete &i;
    break;
}

Это прекрасно работает без части 'delete'. Я добавил его, потому что думал, что память об объекте не освобождается.

Ответы [ 4 ]

10 голосов
/ 30 апреля 2011

Предполагая, что вы вызываете метод набора erase(), обратите внимание, что вызовет деструктор объекта для вас .После того, как вы erase() ваш объект, он уже был delete d, и поэтому ваша вторая попытка вручную вызвать удаление не удастся, так как указатель больше не выделяется.

Для справки см. this

3 голосов
/ 30 апреля 2011

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

  set <myObject*> myobjectlist;     
  myObject *myobject = new myObject;
  myobjectlist.insert(myobject); //insert the pointer, not the object

  for (set<myObject*>::iterator i = myobjectlist.begin(); i != myobjectlist.end(); i++) {
    if ((*i)->myObjectID == myObjectID) {
      myobjectlist.erase(i);
      delete *i;
      break;
    }
  }
3 голосов
/ 30 апреля 2011

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

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

set <myObject> myobjectlist;
myobjectlist.insert(myObject());

В качестве альтернативы, просто сделайте ваш набор set<myObject*>.

Кроме того, стирание требует итератор - нет необходимости разыменовывать его.

2 голосов
/ 30 апреля 2011

Если вам нужен список указателей, используйте список умных указателей.Используйте стандартный алгоритм поиска правильного элемента и удалите его из списка.

#include <set>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>

using namespace boost;

typedef boost::shared_ptr<MyObject> t_object;
std::set<t_object> myObjectList;
myObjectList.insert(t_object(new MyObject));

std::set<t_object>::iterator item = std::find_if(
    myObjectList.begin(), 
    myObjectList.end(), 
    bind(&MyObject::myObjectID, _1)== myObjectID);
if(item!=myObjectList.end())
    myObjectList.erase(item);
...