Функция malloc в C++

Я перехожу на C++ с C. Есть ли в C++ какая-либо польза от функции malloc? Или я могу просто объявить его с ключевым словом «новое». Например:

class Node
{
    ...
}
...
Node *node1 = malloc(sizeof(Node));        //malloc
Node *node2 = new Node;                    //new

Какой из них я должен использовать?


person Mohit Deshpande    schedule 29.04.2010    source источник
comment
Обратите внимание, что в C++ нет неявного приведения типов из void*, поэтому в случае с malloc вам действительно нужно выполнить Node *node1 = reinterpret_cast<Node*>(malloc(sizeof(Node));, что явно требует слишком большого объема ввода. :) (Хорошо, хорошо, вы тоже можете сделать приведение в стиле C, но тогда почему вы кодируете на C++? :))   -  person dash-tom-bang    schedule 30.04.2010
comment
Старайтесь не слишком сильно применять C к C++, это разные языки, в которых все делается по-разному.   -  person GManNickG    schedule 30.04.2010


Ответы (7)


Используйте 1_. Вам не нужно использовать malloc в программе на C++, если только она не взаимодействует с каким-то кодом C или у вас нет причин для особого управления памятью.

Ваш пример node = malloc(sizeof(Node)) - плохая идея, потому что конструктор Node (если он существует) не будет вызываться, а последующий delete node; будет иметь неопределенные результаты.

Если вам нужен буфер байтов, а не объект, вам обычно нужно сделать что-то вроде этого:

char *buffer = new char[1024];

или, желательно, что-то вроде этого:

std::vector<char> buffer(1024);

Обратите внимание, что во втором примере (с использованием std::vector<>) нет необходимости delete объекта; его память будет автоматически освобождена, когда он выйдет за пределы области действия. Вы должны стремиться избегать как new, так и malloc в программах на C++, вместо этого используя объекты, которые автоматически управляют своей собственной памятью.

person Kristopher Johnson    schedule 29.04.2010
comment
Вы также можете использовать malloc, если вы выполняете пользовательское выделение памяти через свой собственный operator::new. - person Troubadour; 30.04.2010
comment
И помните, что new генерирует исключение std::bad_alloc в случае сбоя, если только call не использует модификатор nothrow! - person Gregor Brandt; 30.04.2010
comment
Возможно, следует добавить, что new является типобезопасным, а возврат от malloc — void*. - person Joel; 07.05.2010

Прямой эквивалент malloc() в C++ — это operator new(), который также выделяет необработанную память, однако в большинстве случаев вам нужно выражение new. Выражение new одновременно выделяет соответствующий объем необработанной памяти и инициализирует объект в этой ячейке памяти, возвращая правильно типизированный указатель на новый объект.

В вашем случае new Node правильно, так как он выделяет память и инициализирует новый объект Node. Простой вызов malloc и приведение результата к указателю на Node не приведет к правильному построению объекта Node. Это важно, если Node не является структурой POD (например, когда он или один из его подобъектов имеет конструктор, который следует вызвать).

Вам следует избегать динамического размещения там, где оно не требуется; там, где это необходимо, часто лучше всего инициализировать какой-либо интеллектуальный указатель адресом динамически выделяемого объекта, чтобы невозможно было «забыть» delete объект.

person CB Bailey    schedule 29.04.2010

Одно из основных различий между new и malloc заключается в том, что new вызывает конструктор объекта.

Еще одно отличие состоит в том, что new выдает исключение (может быть обойдено компилятором pragma), если память не может быть успешно выделена. malloc может вызвать генерацию системного сигнала. Хотя некоторые библиотеки C++ реализуют new, вызывая malloc.

Может быть несколько случаев, когда объекты необходимо динамически размещать без вызова их конструкторов. За более чем 20 лет я не сталкивался ни с одним (даже на арене встраиваемых систем).

person Thomas Matthews    schedule 29.04.2010

Ну, единственное, о чем я могу думать, если вы используете new, вам будет не хватать realloc, если он вам понадобится.

person nc3b    schedule 29.04.2010
comment
realloc не работает с типами, отличными от POD, поэтому в C++ почти всегда предпочтительнее использовать vector. - person CB Bailey; 30.04.2010

Ключевая ситуация, в которой вы должны использовать malloc, это если исходный код когда-либо вызывает realloc. Конечно, вы можете переделать все необходимое, но особого преимущества в этом нет.

person Heath Hunnicutt    schedule 29.04.2010
comment
realloc() часто является плохой новостью в C++, поскольку объекты данных, не относящиеся к POD, обычно не любят произвольного перемещения. Вместо этого используйте vector<>. Он не только управляет памятью за вас, но и делает это правильно. - person David Thornley; 07.05.2010
comment
В коде C, который я вижу, realloc почти всегда используется для байтовых массивов или массивов указателей. Оба POD. - person Joshua; 08.02.2014

Моя привычка — использовать malloc() для примитивных типов и C-совместимых структур, а new — для всего остального.

person Joshua    schedule 29.04.2010

В общем, используйте new, за исключением случаев взаимодействия с кодом C.

Ключевым моментом здесь является то, что то, что выделено с помощью new, должно быть освобождено с помощью delete, а то, что выделено с помощью malloc, должно быть освобождено с помощью free. Вы не можете выделить с помощью new и освободить с помощью free() или наоборот. Таким образом, единственный раз, когда вам нужно malloc, это когда вам нужно передать данные какому-то коду C, который может free() или realloc() их.

person Michael Ekstrand    schedule 29.04.2010