#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.
Комментариев нет:
Отправить комментарий