У меня есть такая структура:
class Items
{
private:
struct item
{
unsigned int a, b, c;
};
item* items[MAX_ITEMS];
}
Скажем, я хотел «удалить» элемент, например:
items[5] = NULL;
И позже я создал новый элемент на том же месте:
items[5] = new item;
Мне все еще нужно вызвать в delete[], чтобы убрать это? Или это не понадобится, поскольку границы массива items[] известны до компиляции?
Является ли установка этого указателя на NULL действительной или мне следует вызывать там удаление?





C++ не моя сильная сторона, но я почти уверен, что у вас будет утечка памяти, если вы установите указатель на NULL.
Обновлено: утечка памяти будет памятью, на которую указывает указатель в массиве.
Установка элемента [5] в NULL не удаляет память, связанную с элементом, она просто устанавливает указатель на этот элемент в NULL, поэтому происходит утечка памяти.
Вы можете удалить элемент, позвонив:
delete items[5];
Поскольку в C++ нет автоматической сборки мусора, вам нужно удалить всю память, которая вам больше не нужна.
Перед установкой значения NULL необходимо вызвать delete. (Установка значения NULL не требуется, это просто помогает уменьшить количество ошибок, если вы случайно попытаетесь разыменовать указатель после его удаления.)
Помните, что каждый раз, когда вы используете new, вам нужно будет использовать delete позже с тем же указателем. Никогда не используйте одно без другого.
Кроме того, new [] и delete [] работают вместе одинаково, но никогда не следует смешивать new [] с delete или new с delete []. В вашем примере, поскольку вы создали объект с помощью new (а не new [], который создавал бы массив объектов), вы должны удалить объект с помощью delete (а не delete []).
Как заметил Клюге, вот так вы бы потеряли объект с индексом 5. Но это действительно звучит так, как будто вы не должны делать это вручную, а используйте класс контейнера внутри Item. Если вам на самом деле не нужно хранить эти объекты item в качестве указателей, используйте std::vector<item> вместо этого массива указателей MAX_ITEMS. Вы всегда можете вставить или стереть векторные элементы посередине, если вам нужно.
Если вам нужно сохранить объекты как указатели (обычно, если struct item действительно полиморфна, в отличие от вашего примера), вы можете вместо этого использовать boost :: ptr_vector <item> из Boost.PtrContainer.
Пример:
class Items {
private:
struct item {
unsigned int a, b, c;
};
std::vector<item> items;
}
if (items.size() > 5) // (just to ensure there is an element at that position)
items.erase(items.begin() + 5); // no need to use operator delete at all
Чтобы удалить элемент, используйте:
удалить элементы [5];
после удаления элемента рекомендуется установить удаленный указатель на NULL, чтобы у вас не было ошибки, если вы позже удалите его снова по ошибке.
items [5] = NULL
Say I wanted to 'delete' an item, like so:
items[5] = NULL;
Я мало знаю Visual Basic, но это пахнет идиомой программирования Visual Basic, поскольку «Set a = None» (или Null, я не уверен) удалит объект, на который указывает a (или, скорее, уменьшит его счетчик ссылок для COM объекты).
Как заметил кто-то другой, вы должны использовать либо:
delete items[5];
items[5] = newContent;
или же:
delete items[5];
items[5] = NULL;
После delete[5] единственное возможное использование указателя, хранящегося в items[5], вызывает у вас проблемы. Что еще хуже, это может сработать вначале и начать давать сбои только тогда, когда вы выделяете что-то еще в пространстве, ранее использовавшемся *items[5]. Это причины, которые делают программирование на C / C++ «интересным», то есть действительно раздражающим (даже для тех, кто любит C, как я).
Запись только delete items[5]; спасает то, что может оказаться бесполезной записью, но это преждевременная оптимизация.
Для ясности: вы имеете в виду вызов «delete[]». Думаю, вы имеете в виду delete.
Я упоминаю об этом, потому что в C++ есть два отдельных оператора, operator delete и operator delete[]. Последний используется для удаления массивов объектов, выделенных с помощью operator new[], и применяется ли в этом случае нет. У вас есть массив объектов указатели на, которые вы должны инициализировать многократными вызовами operator new, а не одним вызовом operator new[].
Все, что я действительно пытаюсь сказать, это то, что вы используете delete[] запутанно и неоднозначно; смени его на delete.
Здесь есть несколько связанных вопросов:
struct, поэтому вам не нужно delete[] массив. Если вы создали массив с помощью new[], вам придется его delete[].