exponenta event banner

Недопустимое удаление указателя

Отмена выделения указателя с помощью delete без соответствующего распределения с использованием new

Описание

Этот дефект возникает в следующих случаях:

  • Вы освобождаете блок памяти с помощью delete но память ранее не выделялась с помощью new оператор.

  • Вы освобождаете блок памяти с помощью delete оператор, использующий однообъектную нотацию, но память ранее была выделена как массив с new оператор.

Этот дефект относится только к исходным файлам C++.

Риск

Риск зависит от причины проблемы:

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

  • Если используется однообъектная нотация для delete на указателе, который ранее был выделен с помощью нотации массива для new, поведение не определено.

Проблема также может выделить другие ошибки кодирования. Например, вы, возможно, хотели использовать delete оператор или предыдущий new на другом указателе.

Зафиксировать

Исправление зависит от причины проблемы:

  • В большинстве случаев проблему можно устранить, удалив delete заявление. Если указатель не выделен памяти из кучи с new оператор, не требуется отпускать указатель с помощью delete. При необходимости можно просто повторно использовать указатель или разрешить уничтожение объекта в конце его области.

  • В случае несовпадения обозначений для new и delete, исправьте несоответствие. Например, чтобы выделить и освободить один объект, используйте следующую нотацию:

    classType* ptr = new classType;
    delete ptr;

    Чтобы выделить и освободить объекты массива, используйте следующую нотацию:

    classType* p2 = new classType[10];
    delete[] p2;

Если проблема подчеркивает ошибку кодирования, такую как использование delete или new не на том указателе, исправьте ошибку.

Примеры

развернуть все

void assign_ones(void)
{
    int ptr[10];

    for(int i=0;i<10;i++)
        *(ptr+i)=1;  

    delete[] ptr;   
}

Указатель ptr освобождается с помощью delete оператор. Однако ptr указывает на папку памяти, которая не была динамически выделена.

Исправление: Удаление удаления указателя

Если количество элементов массива ptr известен во время компиляции, одной из возможных корректировок является удаление отмены выделения указателя ptr.

void assign_ones(void) 
{
    int ptr[10];

    for(int i=0;i<10;i++)
        *(ptr+i)=1;  
}
Исправление - Добавление назначения указателя

Если количество элементов массива неизвестно во время компиляции, одной из возможных корректировок является динамическое выделение памяти массиву. ptr с использованием new оператор.

void assign_ones(int num) 
{
    int *ptr = new int[num]; 

    for(int i=0; i < num; i++)
        *(ptr+i) = 1;

    delete[] ptr;
   }
int main (void)
{
    int *p_scale = new int[5];

    //more code using scal

    delete p_scale;
}

В этом примере: p_scale инициализирован массивом размера 5 с использованием new int[5]. Однако p_scale удаляется с помощью delete вместо delete[]. new-delete пара не совпадает. Не использовать delete без скобок при удалении массивов.

Коррекция - совпадение delete кому new

Одним из возможных исправлений является добавление скобок для delete соответствует new [] объявление.

int main (void)
{
    int *p_scale = new int[5];

    //more code using p_scale

    delete[] p_scale;
}
Коррекция - совпадение new кому delete

Другой возможной поправкой является изменение объявления p_scale. Если вы хотите инициализировать p_scale как 5 вместо массива размера 5, необходимо использовать другой синтаксис. Для этого исправления измените квадратные скобки в инициализации на круглые скобки. Оставить delete заявление как есть.

int main (void)
{
    int *p_scale = new int(5);

    //more code using p_scale

    delete p_scale;
}

Информация о результатах

Группа: Динамическая память
Язык: C++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: BAD_DELETE
Воздействие: Высокое
CWE ID: 404
Представлен в R2013b