new [n] и удалить каждое место с помощью delete вместо всего фрагмента с помощью delete [] - PullRequest
1 голос
/ 19 марта 2010

Это действительный C ++ (например, не вызывает UB) и он достигает того, что я хочу, без утечки памяти? Вэлгриндс жалуется на несоответствие free и delete, но говорит, что «утечки невозможны».

int main() {
  int* a = new int[5];
  for(int i = 0; i < 5; ++i)
    a[i] = i;

  for(int i = 0; i < 5; ++i)
    delete &a[i];
}

Причина, по которой я спрашиваю: у меня есть класс, который использует boost::intrusive::list и я new каждый объект, который добавляется в этот список. Иногда я знаю, сколько объектов я хочу добавить в список, и думал о том, чтобы использовать new[] для выделения чанка, и при этом иметь возможность delete каждый объект сам по себе в стиле Disposer boost::intrusive.

Ответы [ 2 ]

8 голосов
/ 19 марта 2010

Ни за что. Вы не можете вызвать delete для того, что не было выделено новым, или вы получили повреждение кучи.

Вы видите, что массив, созданный new [], выделяет не n отдельных объектов, а один массив. Второй объект массива находится в середине блока выделения.

1 голос
/ 19 марта 2010

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

  • полностью несовместимо с delete object синтаксисом
  • несовместимо с наследованием
  • disposer вместо этого явно вызывает деструктор, например, object.~ListItem()
  • должен по-прежнему использовать массив operator new[]
  • Обязательно располагайте объекты в обратном порядке, в отличие от вашего включенного примера
  • Деструктор реализует рефлексивное владение массивом своим первым элементом:

.

ListItem::~ListItem() {
    if ( m_own_my_subarray ) {
        operator delete[]( this ); // does not invoke any destructor!
                 // "this" must be exactly the result of new[]!
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...