Попробуйте поймать и удалить проблему [] - PullRequest
0 голосов
/ 30 сентября 2011

У меня небольшая проблема с ситуацией try-catch, здесь приведен код (он довольно прост):

struct Something
{
  int A, B, C;
  Something()
  {
    A = B = C = 0;
  }
  ~Something()
  {
    cout << "Destructor " << endl;
  }
};

int main()
{
  Something * s = new Something;

  //Something * s = new Something[5];

  try
  {
    delete[] s;
  }
  catch(exception& e)
  {
    delete s;
  }
  return 0;
}

То, что я собираюсь сделать, это сначала попытаться удалить указатель в виде массива, в случае неудачи просто удалить.

Итак, когда я впервые попробовал это с массивом Something (как в закомментированной строке), itr работал отлично. Но когда я пытаюсь сделать это, как сейчас, я получаю ужасную ошибку.

Есть идеи?

Ответы [ 4 ]

7 голосов
/ 30 сентября 2011

То, что вы пытаетесь сделать, не является ни легальным C ++, ни имеет смысл.

За выделением с new должно следовать удаление с delete, а с new[] - delete[];это должно происходить именно так, а все остальное - неопределенное поведение.

Вы не можете "попытаться проверить, правильно ли вы написали код".Исключения сигнализируют об исключительном поведении во время выполнения , но ваша ошибка является статической ошибкой времени компиляции, которая не может быть обработана , но должна быть фиксированной .

Однако в вашем коде никогда не должно быть точки, в которой вы не знаете что означает данный указатель!Поскольку язык является статически типизированным, вы должны в принципе всегда иметь представление о задействованных типах.А если вы хотите передать объекты (возможно, полиморфно), то все, что требует динамического выделения, должно быть заключено в свой собственный класс менеджера (например, shared_ptr или unique_ptr).

4 голосов
/ 30 сентября 2011

Удаление указателя в виде массива (или наоборот) неверно и не определено.Это не приведет к исключению.

Вы должны рассмотреть RAII .Например, создайте класс, который содержит указатель в качестве члена.Конструктор распределяет память, а деструктор удаляет ее.

Тогда у вас есть несколько вариантов:

(1) Есть два конструктора, один для одного элемента и один для массива,Поместите логическое значение в класс, который указывает, указывает ли указатель на один элемент или массив, и проверьте это при уничтожении и вызовите соответствующую функцию удаления.

(2) Сделайте ваш класс шаблоном класса, который принимает логическое значениеПараметр шаблона и разрешите этот выбор во время компиляции.

0 голосов
/ 30 сентября 2011

Вы совершенно не понимаете семантику try / catch.Они не ловят ошибки, они ловят исключения .Вы можете положиться на создаваемое исключение только в том случае, если вы сами его сгенерировали или сделали что-то, что гарантированно сгенерирует исключение.Вызов delete для указателя, выделенного с помощью new[], не гарантирует выдачи исключения, фактически, он не гарантирует ничего конкретного.

0 голосов
/ 30 сентября 2011

Так что мои навыки c ++ ржавые, но delete [] вызывается там, где вы назвали new [].Вы не вызвали new [] в вашем примере.

...