новый оператор для выделения памяти в куче - PullRequest
28 голосов
/ 09 февраля 2011

Я смотрел на подпись нового оператора. Который является:

void* operator new (std::size_t size) throw (std::bad_alloc);

Но когда мы используем этот оператор, мы никогда не используем приведение. * 1004 т.е. *

 int *arr = new int;

Итак, как C ++ преобразовывает указатель типа void* в int* в этом случае. Потому что даже malloc возвращает void*, и нам нужно явно использовать приведение.

Ответы [ 2 ]

41 голосов
/ 09 февраля 2011

Существует очень тонкая разница в C ++ между operator new и оператором new. (Прочтите это снова ... заказ важен!)

Функция operator new является аналогом C ++ функции C malloc. Это необработанный распределитель памяти, в обязанности которого входит создание блока памяти для построения объектов. Он не вызывает никаких конструкторов, потому что это не его работа. Обычно вы не увидите, что operator new используется непосредственно в коде C ++; это выглядит немного странно. Например:

void* memory = operator new(137); // Allocate at least 137 bytes

Оператор new - это ключевое слово, которое отвечает за выделение памяти для объекта и вызывает его конструктор. Это то, что встречается чаще всего в коде C ++. Когда вы пишете

int* myInt = new int;

Вы используете оператор new для выделения нового целого числа. Внутри оператор new работает примерно так:

  1. Выделите память для хранения запрошенного объекта, используя operator new.
  2. Вызвать конструктор объекта, если таковой имеется. Если это вызывает исключение, освободите вышеуказанную память с помощью operator delete, а затем распространите исключение.
  3. Возвращает указатель на вновь созданный объект.

Поскольку оператор new и operator new разделены, можно использовать ключевое слово new для создания объектов без фактического выделения памяти. Например, известное размещение нового позволяет вам построить объект по произвольному адресу памяти в предоставленной пользователем памяти. Например:

T* memory = (T*) malloc(sizeof(T)); // Allocate a raw buffer
new (memory) T(); // Construct a new T in the buffer pointed at by 'memory.'

Перегрузка оператора new путем определения пользовательской функции operator new позволяет использовать new таким образом; вы указываете, как происходит распределение, и компилятор C ++ подключает его к оператору new.

Если вам интересно, ключевое слово delete работает аналогичным образом. Есть функция освобождения, называемая operator delete, отвечающая за удаление памяти, а также оператор delete, отвечающий за вызов деструкторов объектов и освобождение памяти. Однако operator new и operator delete могут использоваться вне этих контекстов вместо C, например, malloc и free.

5 голосов
/ 09 февраля 2011

Вы путаете выражение new с функцией operator new().Когда первый компилируется, компилятор среди других вещей генерирует вызов функции operator new() и передает размер, достаточный для хранения типа, упомянутого в выражении new, и затем возвращается указатель этого типа.

...