Оператор delete и массивы?

Я имею abstract Base класс и Derived класс.

int main ()
{
  Base *arrayPtr[3];

  for (int i = 0; i < 3; i++)
  {
    arrayPtr[i] = new Derived();
  }

  //some functions here

  delete[] arrayPtr;

  return 0;
}

Я не уверен, как использовать оператор delete. Если я удалю массив указателей базового класса как показано выше, то это назовет деструкторы объектов производного класса и уберет память?

6
задан Unihedron 11 August 2014 в 07:29
поделиться

11 ответов

[

] Нужно выполнить итерацию над элементами массива, [] удалить [] каждый из них. Затем вызвать [], если массив был динамически выделен, вызов [] delete [][], используя [] new[][]. [][

] [

] В вашем примере кода массив выделен на стеке, поэтому нельзя вызывать [] delete [][] на нем.[

] [

] Также убедитесь, что ваш класс [] Base[] имеет [] виртуальный[] деструктор.[

] [

] Ссылка: []Когда мой деструктор должен быть []виртуальным[][].[

].
10
ответ дан 8 December 2019 в 03:53
поделиться
[

]Вы смешиваете парадигмы -- Оператор delete массива предназначен для освобождения памяти, выделяемой оператором new массива, но вы выделяете массив на стеке как массив указателей, а затем выделяете объект для каждого члена массива. В коде необходимо выполнить итерацию через массив.[

] [

]Чтобы использовать оператор array new, нужно объявить так:[

] [
Base *array;
array = new Base[3];
/* do stuff */
delete[] array;
] [

]Это выделяет сопряженную область памяти для трех объектов -- обратите внимание, что у вас есть массив объектов Base, а не массив указателей на объекты Base.[

].
0
ответ дан 8 December 2019 в 03:53
поделиться
[

]Нет, это не совсем то, что вы хотите. [

] [

]Здесь нужно обратить внимание на два момента:[

] [
    ] [
  1. ][

    ]Синтаксис []delete[] arrayPtr[] используется, если вы динамически выделяете массив, например:[

    ] [
    ][]arrayPtr = new (Base *)[mylength];
    [][
    ] [

    ]В вашем случае, однако, есть статически выделенный массив, поэтому нет необходимости его удалять. Однако необходимо удалять отдельные элементы массива:[

    ] [
    ][]for ( int = i; i < 3; i++ )
     удалить arrayPtr[i];
    [][
    ][
  2. ] [
  3. ][

    ]Второй момент, о котором необходимо позаботиться, это сделать деструктор класса []Base[] виртуальным:[

    ] [
    ][]class Base
    {
     виртуальная ~Base();
     /* ... */
    };
    [][
    ] [

    ]Это гарантирует, что при вызове delete на []Base *[], который на самом деле указывает на []Derived[], будет вызван деструктор []Derived[], а не только деструктор []Base[].[

    ][
  4. ] [
]
0
ответ дан 8 December 2019 в 03:53
поделиться
[

]Нет, вы должны явно удалить каждый элемент массива:[

] [
for (int i = 0; i < 3; ++i)
{
    delete arrayPtr[i];
}
]
10
ответ дан 8 December 2019 в 03:53
поделиться
[

]Вместо этого нужно сделать:[

] [
 for ( int = i; i < 3; i++ )
 {
    delete arrayPtr[i];
 }
] [

]И не делать []delete[] arrayPtr;[], так как вы пытаетесь освободить/удалить выделенный стек []arrayPtr[].[

] [

]Вместо массива следует использовать []std::vector[] указателей. А если Вы используете компилятор, реализующий TR1, то вместо сырых указателей можно использовать []std::vector[] из []std::tr1::shared_ptr[], и тогда Вам не нужно будет беспокоиться об удалении этих объектов самостоятельно.[

] [

]Пример:[

] [
{
    std::vector< std::tr1::shared_ptr<Base> > objects;
    for (int i=0; i < 3; ++i)
    {
        objects.push_back(std::tr1::shared_ptr<Base>(new Derived()));
    }
}  // here, once "objects" exit scope, all of your Derived objects are nicely deleted
]
2
ответ дан 8 December 2019 в 03:53
поделиться
[

]Необходимо удалять члены массива по отдельности. Также необходимо убедиться, что в базовом классе имеется виртуальный деструктор. Также можно подумать о том, чтобы сделать его массивом (а еще лучше - std::vector) умных указателей, таких как boost::shared_ptr.[

].
1
ответ дан 8 December 2019 в 03:53
поделиться
[

] Нет, так нельзя. Как предлагали другие, вы должны просмотреть каждый пункт и удалить его. Это очень простое правило для запоминания. Если вы выбрали []new[], то используйте [] delete[], а если вы использовали [] new[][], то используйте [] delete[][][

]
1
ответ дан 8 December 2019 в 03:53
поделиться
[

] Заметьте, что отсутствует:[

] [
int main() {
  boost::ptr_vector<Base> v;
  for (int i = 0; i < 3; i++) v.push_back(new Derived());
  // some functions here, using v[0] through v[2]
}
] [

] Проверьте [] контейнеры указателей Boost[]. [

]
1
ответ дан 8 December 2019 в 03:53
поделиться
[

]Оператор delete должен совпадать с оператором new на этом указателе, если он был выделен с []new[][], то вы должны вызвать []delete[][] и наоборот;[

] [
int* pInt = new int;
delete pInt; OK
delete [] pInt; WRONG

int[] pIntArr = new int[3];
delete [] pIntArr; OK
delete pIntArr; WRONG
] [

]В вашем случае что-то не так - вы пытаетесь []удалить [], который был выделен на стеке. Это не сработает.[

] [

]В данном случае вы должны удалить каждый указатель по отдельности.[

]
1
ответ дан 8 December 2019 в 03:53
поделиться
[

] То, что у вас есть, является неопределенным поведением -- ошибка. Каждый вызов на []new[] должен быть сопоставлен с []delete[]; каждый вызов на []new[][] должен быть сопоставлен с []delete[][]. Они разделены и не могут быть смешаны.[

] [

]В выложенном вами коде на стеке выделен массив указателей на Base. Затем вы вызываете []delete[][] на массив, выделенный на стеке -- вы не можете этого сделать. Вы можете только []delete[][] массив, выделенный на куче с помощью []new[][]. [

] [

]Для каждого элемента, выделенного с []new[] -- или предпочтительнее использовать контейнерный класс, такой как []std::vector[], вместо массива нужно вызвать []delete[]. [

]
1
ответ дан 8 December 2019 в 03:53
поделиться
[

]Убедитесь, что в []Base[] есть виртуальный деструктор. Затем, как и в случае с []fretje, описанным[], удаляем каждый элемент массива, затем массив.[

] [

]Для массива следует использовать []std::vector[]. При этом следует использовать []действительно [] контейнер, созданный для такого рода вещей. (Чтобы случайно не удалить все элементы, что определенно произойдет, если будет выброшено исключение!). В Boost есть []такая библиотека [].[

].
0
ответ дан 8 December 2019 в 03:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: