удалить и удалить [] то же самое в Visual C ++? - PullRequest
6 голосов
/ 19 ноября 2008

Я знаю, что я должен использовать delete [] после того, как использую new [], поэтому использование auto_ptr с new [] не такая хорошая идея.

Однако при отладке delete [] (с использованием Visual Studio 2005) я заметил, что вызов перешел в функцию, которая выглядела так:

void operator delete[]( void * p )
{
    RTCCALLBACK(_RTC_Free_hook, (p, 0))
    operator delete(p);
}

Означает ли это, что синтаксис [] потерян в Visual C ++? Если так, то почему? Чтобы избавить разработчика от необходимости запоминать правильный синтаксис?

Ответы [ 5 ]

26 голосов
/ 19 ноября 2008

Рассмотрим этот код:

class DeleteMe
{
public:
  ~DeleteMe()
  {
    std::cout << "Thanks mate, I'm gone!\n";
  }
};

int main()
{
  DeleteMe *arr = new DeleteMe[5];
  delete arr;
  return 0;
}

Если вы запустите его в VS2005, он напечатает:

Thanks mate, I'm gone!

Если вы измените main() на правильное соответствие стандарту C ++:

int main()
{
  DeleteMe *arr = new DeleteMe[5];
  delete[] arr;
  return 0;
}

Будет напечатано:

Thanks mate, I'm gone!
Thanks mate, I'm gone!
Thanks mate, I'm gone!
Thanks mate, I'm gone!
Thanks mate, I'm gone!

Не стреляйте себе в ногу. VS2005 будет НЕ делать правильные вещи, если вы не соответствуете различным вариантам нового / удаления. Ни один другой стандартный C ++ совместимый компилятор не будет.

Вокруг operator new и operator delete (и их различных разновидностей) происходит некоторая магия компилятора, в основном, вызовы ctors и dtors добавляются за кулисами. Эта магия зависит от этих маленьких скобок [], поэтому не теряйте их, иначе вы потеряете магию.

4 голосов
/ 19 ноября 2008

Полагаю, это просто деталь реализации. Их распределитель кучи работает так же, когда освобождает массивы и указатели.

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

2 голосов
/ 19 ноября 2008

Удаление массива без [] только освободит память, но НЕ вызовет деструкторы в каждом объекте в массиве. Итак, технически вам нужно только [], если ваш деструктор должен быть вызван.

2 голосов
/ 19 ноября 2008

Возможно, у удаленных вами данных не было деструкторов? Если это так, это простое удаление будет иметь смысл. Это работает на пустоте * в конце концов.

В любом случае, вы должны использовать delete [], чтобы убедиться, что деструктор запущен для каждого элемента в массиве.

2 голосов
/ 19 ноября 2008

То, что сейчас они могут работать одинаково, не означает, что вы обязательно можете обращаться с ними одинаково - поведение может измениться. И кроме того, кого это волнует - вы должны написать свой код, чтобы вам не пришлось запоминать.

Кроме того, вы можете использовать scoped_array для удаления массива.

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