2010-04-29 11 views
6

Je suis en transition vers C++ à partir de C. En C++, y a-t-il une utilité pour la fonction malloc? Ou puis-je le déclarer avec le "nouveau" mot-clé? Par exemple:Fonction Malloc en C++

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

Lequel dois-je utiliser?

+0

Notez que dans C++ il n'y a pas de distribution implicite de void *, donc sur le malloc, vous devez faire 'Node * node1 = reinterpret_cast (malloc (sizeof (Node));' qui est clairement trop typé. :) (Ok ok vous pouvez aussi faire un casting de style C, mais alors pourquoi codifiez-vous en C++?) –

+5

Essayez de ne pas trop appliquer C à C++, ce sont des langages différents avec des choses faites de différentes façons. – GManNickG

Répondre

20

Utilisez new. Vous ne devriez pas avoir besoin d'utiliser malloc dans un programme C++, sauf s'il interagit avec du code C ou si vous avez des raisons de gérer la mémoire d'une manière spéciale.

Votre exemple de node = malloc(sizeof(Node)) est une mauvaise idée, parce que le constructeur de Node (le cas échéant existe) ne serait pas appelé, et une delete node; ultérieure aurait des résultats non définis.

Si vous avez besoin d'un tampon d'octets, au lieu d'un objet, vous aurez envie généralement faire quelque chose comme ceci:

char *buffer = new char[1024]; 

ou, de préférence, quelque chose comme ceci:

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

Notez que pour le deuxième exemple (en utilisant std::vector<>), il n'y a pas besoin de delete l'objet; sa mémoire sera automatiquement libérée lorsqu'elle sortira de sa portée. Vous devez vous efforcer d'éviter à la fois new et malloc dans les programmes C++, en utilisant à la place des objets qui gèrent automatiquement leur propre mémoire.

+7

Vous pouvez également utiliser 'malloc' si vous faites une allocation de mémoire personnalisée via votre propre' operator :: new'. – Troubadour

+1

Et rappelez-vous que new lance une exception std :: bad_alloc en cas d'échec à moins d'appeler avec le modificateur nothrow! –

+1

Devrait peut-être ajouter que new est de type safe, alors que le retour de malloc est nul *. – Joel

8

L'équivalent direct de malloc() en C++ est operator new() qui alloue également de la mémoire brute, mais dans la plupart des cas une expression new est ce que vous voulez. Une expression new alloue une quantité appropriée de mémoire brute et initialise un objet dans cet emplacement de mémoire, renvoyant un pointeur correctement typé au nouvel objet.

Dans votre cas, new Node est correct car il alloue de la mémoire et initialise un nouvel objet Node. Appelez simplement malloc et le résultat de la diffusion à un pointeur vers Node ne construira pas correctement l'objet Node. Ceci est critique si Node n'est pas une structure POD (par exemple quand elle ou l'un de ses sous-objets a un constructeur qui devrait être appelé).

Vous devez éviter l'allocation dynamique là où elle n'est pas nécessaire; là où c'est nécessaire, il est souvent préférable d'initialiser une sorte de pointeur intelligent avec l'adresse de l'objet alloué dynamiquement afin qu'il ne soit pas possible d'oublier delete l'obejct.

2

Eh bien, la seule chose à laquelle je peux penser, si vous utilisez un nouveau, vous allez manquer realloc si vous en avez besoin.

+3

'realloc' ne fonctionne pas avec les types non-POD donc l'utilisation d'un' vector' est presque toujours préférable en C++. –

1

La situation clé dans laquelle vous devez utiliser malloc est si le code original appelle realloc. Bien sûr, vous pouvez réimplémenter tout ce dont vous avez besoin, mais il n'y a pas beaucoup d'avantages à le faire.

+0

'realloc()' est souvent une mauvaise nouvelle en C++, car les objets de données non-POD sont généralement allergiques à un déplacement arbitraire. Utilisez un 'vecteur <>' à la place. Il ne fait pas seulement la gestion de la mémoire pour vous, il le fait correctement. –

+0

Dans le code C que je vois, realloc est presque toujours utilisé sur les tableaux d'octets ou les tableaux de pointeurs. Les deux sont POD. – Joshua

1

Mon habitude est d'utiliser malloc() pour les types primitifs et les structures compatibles C, et nouveau pour tout le reste.

3

L'une des principales différences entre new et malloc est que new appellera le constructeur de l'objet.

Une autre différence est que new lèvera une exception (peut être contournée par un compilateur pragma) si la mémoire ne peut pas être allouée avec succès. Le malloc peut provoquer la génération d'un signal système. Bien que certaines bibliothèques C++ implémentent new en appelant malloc.

Il peut y avoir quelques cas où les objets doivent être alloués dynamiquement sans invoquer leurs constructeurs. En plus de 20 ans, je n'en ai rencontré aucun (pas même dans l'arène des systèmes embarqués).

1

En général, utilisez new sauf en cas d'interfaçage avec le code C.

Le point clé est ce que ce qui est alloué avec new doit être libéré avec delete, et ce qui est alloué avec malloc doit être libéré avec free. Vous ne pouvez pas allouer avec new et gratuitement avec free() ou vice versa. Donc, à peu près la seule fois où vous avez besoin malloc est lorsque vous avez besoin de transmettre des données à un code C qui pourrait free() ou realloc().