Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

delete [] и перемещения

#cpp #language_lawyer


int* a = new int[4];
++a;
--a;
delete [] a;


Будет валидным такой код?

А вот такой:

int* a = new int[4];
++a;
delete [] a;


Необходимо просто что бы какой нибудь указатель указывал на начало динамического
выделенного массива? И как распознается длинна массива которую нужно уничтожить? 

Может быть по типу? Но указатель указывает только на первый элемент в массиве, int*,
а не ( * a)[4]. И как можно привести во втором коде int* к (*a)[4]? Почему нет неявного
приведения?
    


Ответы

Ответ 1



Данный фрагмент кода совершенно корректный, так как оператор delete использует значение, хранящееся в указателе, которое равно значению, ранее полученному с использованием оператора new. int* a = new int[4]; ++a; --a; delete [] a; Для оператора совершенно неважно, какое до этого в указателе было значение, и как оно изменялось. Чтобы это сделать еще более наглядным то вы можете написать, например, int x; int *px = &x; int* a = new int[4]; px = a; a = &x; delete [] px; Однако данный фрагмент кода int* a = new int[4]; ++a; delete [] a; некорректный, так как указатель a не содержит адрес выделенной динамически памяти. delete и free должны применятся к значению указателя полученому по new или malloc: это требование стандарта. Обычно "под капотом" оператора new делается следующее. К запрашиваемому размеру памяти, который вы хотите выделить, добавляется к началу блока префикс, который будет хранить этот размер блока памяти. И адрес этого префикса просто вычисляется как смещение на размер слова (обычно sizeof( int) ) от начала участка памяти, адрес которой возвращается пользователю оператора new. Это значение используется, чтобы при удалении памяти правильно оценить ее размер. Что касается вашего второго вопроса, то вы можете написать, например, int* a = new int[4]; int ( *p )[4] = reinterpret_cast( a );

Комментариев нет:

Отправить комментарий