#cpp #delete
Ясное дело, что по Стандарту вызовы malloc()/free()*, **new/delete и new[]/delete[]
должны быть строго парными, иначе неопределенное поведение.
Хотя я и видел в очень крупных и серьезных проектах что-то вроде:
float *f = new float[count];
// ...
delete f;
Разработчики обосновывали такую запись так: мол, тип элементарный, деструктора не
имеет, можно делать delete и не париться, за несколько лет разработки с этим ни разу
не возникло проблем.
...но мы-то с вами знаем, что это неопределенное поведение, и в очередную пятницу
тринадцатого компилятор решит скомпилировать код запуска всех ядерных ракет...
Меня беспокоит пара других вопросов:
1)
Type *f = new Type[1];
delete f;
Это неопределенное поведение?
2)
struct Type
{
int a, b, c;
float values[10];
};
Type *f = new Type[count];
free(f);
Даже если Type не содержит деструктора и динамических данных, например, если это
структура/класс из нескольких объектов элементарных типов, это все равно неопределенное
поведение?
Ответы
Ответ 1
Формально - да, неопределенное, так как для выделения вызывается оператор new для массива, пусть и из одного элемента, а delete - нет. Уж это точно неопределенное, потому как new/delete и malloc/free вообще могут использовать разные механизмы работы с памятью. "По-моему, так." (с) ПухОтвет 2
1. На первый взгляд в этом примере: Type *f = new Type[1]; delete f; Компилятор может понять, что запрашивается один элемент. Но в общем случае оператор new не анализирует количество запрашиваемых элементов массива хотя бы потому, что в общем случае это количество может быть известно только в рантайме. Поэтому Type *f = new Type[1]; delete f; однозначно неправильно. Ведь на месте единицы может быть переменная, значение которой вводит пользователь. Например: int size; cin>>size; Type *f = new Type[size]; delete f; 2. Однозначно нельзя запрашивать память new а освобождать free. Это вообще из другой оперы. Парный оператор для new это delete.
Комментариев нет:
Отправить комментарий