Создание класса с использованием указателя, выделенного функцией 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 не сможет правильно его удалить).