Утечка при попытке освободить элемент вектора - PullRequest
0 голосов
/ 04 марта 2012

, пожалуйста, помогите понять это.У меня есть утечка кода, и я не знаю, как с этим справиться

vector <ItemClass> items( 10 );
items[1] = ItemClass( "DVD Player", 560 );
items[5] = * new ItemClass( "Blu Ray Player", 900 );

Как мне освободить память для предметов [5]?Я получаю сообщение об ошибке при попытке освободить память

delete &items[5];

delete [] &items[5];

Я даже пытался что-то вроде

ItemClass * delItem = &items[5];
items[5] = item4;
delete delItem;

Я получаю "повреждение кучи" в VS2010 Ultimate

Ответы [ 2 ]

1 голос
/ 04 марта 2012

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

Используйте delete только для объектов. См. Код ниже.

Используйте delete [] только для "собственных" массивов, но не для векторных или подобных контейнерных классов или объектов внутри них.

Я не буду приводить пример для массивов, поскольку массивы могут быть более запутанными.

Стек примеров по умолчанию:

vector <ItemClass> items( 10 );

// does not need to be deleted because item is on the stack
ItemClass item("device1", "10"); 
items.push_back(item);

Пример по умолчанию с выделением кучи:

vector <ItemClass*> items( 10 );

ItemClass* pItem = new ItemClass("device2", "20");
items.push_back(pItem);

// delete all items inside vector
for (int i = 0; i < items.size(); i++)
{
    ItemClass* pToDelete = items[i];
    delete pToDelete;
    items.erase(i);
}

Следующие примеры следует избегать и предназначены только для разъяснения! Используйте на свой страх и риск.

Хранение адресов переменных стека:

vector <ItemClass*> items( 10 );

// does not need to be deleted because item is on the stack
ItemClass item("device3", "30"); 
items.push_back( &item ); // storing a reference to item

// No need to delete this item that points to something on the stack.
// However you might not be able to tell items apart which have been 
// created on the heap or the stack, so just dont do it.

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

Хранение разыменованных элементов:

vector <ItemClass> items( 10 );

ItemClass* pItem = new ItemClass("device4", "40"); 
items.push_back(*pItem);

// must be deleted because allocated on the heap
// Again you can not tell which item is allocated on stack or heap. Avoid this.
1 голос
/ 04 марта 2012

Вы не вызываете delete для объектов, которые вам не принадлежат. Вы не владеете items[5]. Вектор принадлежит items.

То, что вам нужно для delete, - это объект ItemClass, который вы в данный момент используете, который вы создаете с помощью new ItemClass(...) и затем копируете в items[5].

ItemClass *temp = new ItemClass("Blue Ray Player", 900);
items[5] = *temp;
delete temp;

Если вы хотите удалить items[5] из вектора, попросите вектор удалить его:

items.erase(items.begin() + 5);

Обратите внимание, что это может быть довольно неэффективно, потому что все более поздние элементы в векторе должны быть перемещены вниз на одну позицию, что влечет за собой вызов оператора присваивания ItemClass один раз для каждого перемещенного элемента.

Вместо этого вы можете использовать вектор указателей на ItemClass, или вектор shared_ptr s, или boost::ptr_vector.

...