new и delete
Функции
malloc и
calloc не обеспечивают соответствия между размером выделенной памяти и типом данных.
double *p; //
...
p=calloc(n,sizeof(int)); //
Результат
calloc имеет тип
void *, который в C может быть преобразован к указателю любого типа без явного вызова операции преобразования, но даже использование явного преобразования результата не гарантирует, что в аргументах не будет ошибки:
p=(double *)calloc(n,sizeof(int));
Кроме того, многие программисты не заботятся о проверке результата функции на 0, считая, что памяти много.
Для устранения недостатков функций
malloc,
calloc и
free в С++ были введены операции
new и
delete.
Операция new возвращает
типизированный указатель, а после выделения памяти вызывается конструктор, который инициализирует память. Если память не может быть выделена, возникает исключительная ситуация
bad_alloc, т.е. проверять возвращаемое значение на 0 нет необходимости. Допускаются следующие формы для операции
new:
- new тип
- new тип()
- new тип[выражение]
- new тип[выражение]()
- new тип[выражение]{список выражений}
- new тип(список выражений) или new тип{список выражений}
3-я, 4-я и 5-я форма используется для создания массива объектов, остальные – для создания одиночных объектов. Различие между 1-й и 2-й, 3-й и 4-й формами проявляется только для стандартных типов данных и классов без конструкторов. В 1-м и 3-м случаях состояние объектов остается неопределенным, во 2-м и 4-м – инициализируется 0. Для классов с конструкторами в первых четырех формах вызывается конструктор по умолчанию. 5-я и 6-я форма предназначена для инициализации созданного объекта (массива объектов) с помощью конструктора с параметрами, а для стандартных типов данных можно указать только одно выражение, значение которого используется для инициализации созданного объекта.
Операция delete освобождает память, предварительно вызвав деструктор для объектов. Существуют две формы операции
delete:
- delete указатель
- delete[] указатель
1-я форма используется для уничтожения одиночного объекта, 2-я форма – массива объектов.
Примеры:
int *p;
p=new int(10);
...
delete p;
p=new int[10];
...
delete[] p;
Нельзя смешивать формы
new и
delete. Нельзя выделять память с помощью функций
malloc и
calloc, а освобождать с помощью
delete, или выделять с помощью
new, а освобождать с помощью
free даже для стандартных типов данных, не требующих вызова конструкторов и деструкторов, так как эти операции могут сохранять дополнительную информацию о выделенной памяти или использовать другую реализацию кучи.