Удалить массив указателей без удаления указанных объектов в памяти? - PullRequest
1 голос
/ 28 ноября 2011

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

Я пишу процедуру ограничения для HashSet, которую я реализовал пару дней назад, поэтому, когда хеш-таблица заполнена, она заменяется другой таблицей двойного размера. Я представляю хеш-таблицу, используя массив указателей на объект (User), а сам массив объявляется динамически в моем классе HashSet, поэтому его можно удалить после копирования всего его содержимого в новую таблицу с помощью хеш-функция.

Так что в основном мне нужно:

  1. Объявите другую таблицу с размером, равным двойному размеру исходного массива.
  2. Скопируйте каждый указатель на User объекты из моего исходного массива в новый, применяя мою хэш-функцию (он получает объект User из памяти и вычисляет индекс, используя строку, представляющую имя пользователя).
  3. После вставки всех указателей из исходного массива в новый, мне придется освободить выделенную память для исходного массива и заменить указатель в моем классе HashSet (член private userContainer) на местоположение нового один (массив).

Проблема в том, что если я использую delete[] userContainer, чтобы освободить выделенную для него память, он также удалит каждый объект в памяти, поэтому вновь созданный замещающий массив будет указывать на свободные позиции в памяти!

Ответы [ 4 ]

4 голосов
/ 28 ноября 2011

То, что вы описываете, звучит неправильно.
Допустим, у вас есть class A и вы создаете массив A с:

A** array1 = new A*[32];

Затем заполните:

for(int i = 0; i < 32; ++i)
    array1[i] = new A();

Выполнение delete[] array1 не освобождает элементы array1.

Так что это безопасно:

A** array1 = new A*[32];
for(int i = 0; i < 32; ++i)
    array1[i] = new A();

A** arary2 = new A*[64];
for(i = 0; i < 32; ++i)
   array2[i] = array1[i];

delete [] array1;

for(i = 0; i < 32; ++i)
    // do something with array2[i]
2 голосов
/ 28 ноября 2011

Я не думаю, что ваша проблема существует.Вот детский пример, показывающий, что беспокоиться не о чем:

Foo * brr[10];

{
   Foo * arr[10]; 

   // This is not touching the objects!
   for (Foo * it = arr; it != arr + 10; ++it) *it = new Foo;

   std::copy(arr, arr + 10, brr);

}  // no more arr

for (Foo * it = brr; it != brr + 10; ++it) delete *it;  // fine

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

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

2 голосов
/ 28 ноября 2011

Как правило, при удалении массива указателей все объекты, на которые указатели указывали, остаются в существовании.Фактически, это потенциальный источник больших утечек памяти.

Но в некоторой среде с подсчетом ссылок (например, Objective-C или Qt), когда вы удаляете массив OBJECT (против простого * 1003)* массив), тогда счетчики ссылок уменьшаются, и объекты будут удалены, если счетчик станет равным нулю.

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

(Это поможет узнать, с каким языком вы имеете дело, и что вы подразумеваете под "массивом".)

1 голос
/ 28 ноября 2011

Знаете ли вы разницу между malloc / free, new / delete и new[] / delete[]? Я полагаю, что вы, возможно, захотите не использовать new[] / delete[] в вашей ситуации, так как вы не хотите вызывать деструкторы, я полагаю?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...