2010-04-29 4 views
6

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

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

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

+0

Обратите внимание, что в C++ не существует неявного приведения из void *, поэтому в случае с malloc вам нужно фактически выполнить 'Node * node1 = reinterpret_cast (malloc (sizeof (Node)), что явно чересчур печатает. :) (Хорошо, вы тоже можете сделать C-стиль, но почему вы кодируете на C++? :) –

+5

Старайтесь не применять C на C++ слишком много, они разные языки с вещами, сделанными по-разному. – GManNickG

ответ

20

Использование new. Вам не нужно использовать 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++, вместо этого используя объекты, которые автоматически управляют собственной памятью.

+7

Вы также можете использовать 'malloc', если вы произвольно занимаетесь распределением памяти через свой' operator :: new'. – Troubadour

+1

И помните, что новый выдает исключение std :: bad_alloc при ошибке, если не вызвал вызов с модификатором nothrow! –

+1

Следует добавить, что новый тип безопасен, а возврат из malloc недействителен *. – Joel

8

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

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

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

2

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

+3

'realloc' не работает с не-POD-типами, поэтому использование' vector' почти всегда является предпочтительным в C++. –

1

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

+0

'realloc()' часто бывает плохой новостью на C++, поскольку объекты данных, отличные от POD, обычно имеют аллергию на произвольное перемещение. Вместо этого используйте 'vector <>'. Это не только управление памятью для вас, но и правильное. –

+0

В коде C, который я вижу, realloc почти всегда используется на байт-массивах или указательных массивах. Оба являются POD. – Joshua

1

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

3

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

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

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

1

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

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

Смежные вопросы