printУлучшения языка C

printnew и delete

Функции malloc и calloc не обеспечивают соответствия между размером выделенной памяти и типом данных.
double *p; // до модификации int *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 даже для стандартных типов данных, не требующих вызова конструкторов и деструкторов, так как эти операции могут сохранять дополнительную информацию о выделенной памяти или использовать другую реализацию кучи.
loading