Создание класса с использованием указателя, выделенного функцией malloc()

Возможный дубликат:
C++ - "размещение новых"
Помогите с утверждением C++

Я работаю над продуктом, где большинство модулей написаны на C. Среди них один или два модуля написаны на C++. Я нахожу ниже код в модуле C++, который я не мог понять, что происходит.

a = (char *) malloc (size);
b = new (a) MyClass();

Может кто-нибудь объяснить мне, как указатель, выделенный malloc, используется для нового оператора? Это законно?

Спасибо!

3 ответа

Решение

b = new (a) MyClass(); называется размещение нового и создает новый объект типа MyClass на заранее выделенной памяти (память, указатель a указывает на).

Вам также следует проверить этот вопрос: какие варианты использования используются для "размещения новых"?

new может принимать параметр, который сообщает new начальный адрес памяти... так что код делает...

a = (char *) malloc (size);

выделить память нового класса...

b = new (a) MyClass();

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

Синтаксис new (something) Type называется размещение нового. Как все new, он вызывает функцию распределителя, а затем конструктор Type, Функция распределителя имеет подпись:

    void * оператор new( size_t byteCount, что-то);

Другими словами, все, что вы помещаете в скобки, передается в качестве дополнительных аргументов operator new функция.

В дополнение к обычному operator new функция, стандарт определяет два других operator new функции, которые принимают дополнительные аргументы:

void* operator new( size_t byteCount, std::nothrow_t ) noexcept;

а также

void* operator new( size_t byteCount, void* where ) noexcept;

Обратите внимание, что оба noexcept, Первый возвращает нулевой указатель в случае неудачного размещения (вместо bad_alloc), а второй просто возвращает where, (Второе также называется новым размещением. Это не приводит к путанице: "новое размещение" может относиться к любому расширенному новому или просто к тому, который занимает void*.)

В вашем случае используется второй, хотя я бы серьезно усомнился, почему: если у типа объекта есть деструктор, вам придется сделать:

b->~MyClass();
free( b );

удалить его. (Размещение new и явное удаление обычно используются в тех случаях, когда вы хотите отделить распределение от инициализации. В реализации std::vectorНапример, если емкость может быть больше размера.) Единственная причина, по которой я вижу это, заключается в том, что объект должен быть размещен в C++, но будет удален в C (и, конечно, он имеет тривиальный деструктор - в противном случае C не сможет правильно его удалить).

Другие вопросы по тегам