Поделиться через


C6278

Предупреждение C6278: <переменная> выделяется с массивом new [], но удаляется скалярной операцией delete. Деструкторы не будут вызваны.

Это предупреждение возникает только в коде C++ и указывает, что вызывающая функция выделила память при помощи оператора массива new [], но высвободила память при помощи скалярного оператора delete. Это является неопределенным поведением согласно стандарту C++ и реализации Microsoft VC++. Существует по крайней мере три причины возникновения неполадок из-за этого.

  • Для отдельных объектов в массиве вызываются конструкторы, но не вызываются деструкторы. 

  • Если глобальный (или относящийся к определенному классу) оператор new и оператор delete несовместимы с оператором new[] и оператором delete[], могут возникнуть непредвиденные результаты.

  • Не следует полагаться на неопределенное поведение, поскольку это весьма рискованно.

Последствия этой неполадки трудно спрогнозировать в точности. Для классов, для которых деструкторы осуществляют отмену выделения памяти, возможны утечки; возможно неоднородное поведение классов с деструкторами, выполняющими семантически различные операции; возможно повреждение памяти и сбои при переопределении операторов. В прочих случаях несоответствие не имеет большого значения (это зависит от реализации компилятора и его библиотек). Программа анализа не всегда различает эти ситуации.

Если память выделяется при помощи оператора массива new [], ее, как правило, следует высвобождать при помощи оператора массива delete[].

Пример

Это предупреждение создается в следующем примере кода:

class A
{
  // members
};

void f( )
{
  A *pA = new A[5];
  // code ...
  delete pA;
}

Чтобы исправить это предупреждение, используйте следующий код:

void f( )
{
  A *pA = new A[5];
  // code ...
  delete[] pA;
}

Если нижележащий объект в массиве имеет примитивный тип, такой как int, float, enum или указатель, нет необходимости вызывать деструктор. В этих случаях возникает предупреждение C6283.