2010-03-23 4 views
7

Mon programme C++ a besoin d'un bloc de mémoire non initialisée et d'un pointeur void* pour que je puisse le donner à une bibliothèque tierce. Je veux passer le contrôle de la durée de vie du bloc à la bibliothèque, donc je ne veux pas utiliser std::vector. Lorsque la bibliothèque est terminée avec le bloc, elle appelle un callback que je dois fournir et qui libère le bloc. En C je voudrais utiliser malloc() et plus tard free().Lequel utiliser - "operator new" ou "operator new []" - pour allouer un bloc de mémoire brute en C++?

En C++ je peux appeler soit ::operator new ou ::operator new[] et ::operator delete ou operator delete[] respectivement plus tard:

void* newBlock = ::operator new(sizeOfBlock); 
// then, later 
::operator delete(newBlock); 

On dirait que les deux ::operator new et ::operator new[] ont exactement la même signature et exactement le même comportement. La même chose pour ::operator delete et ::operator delete[]. La seule chose que je ne devrais pas faire est d'appairer operator new avec operator delete[] et vice versa - comportement indéfini. A part ça, quelle paire dois-je choisir et pourquoi?

+5

Je suppose que vous savez que vous devriez utiliser 'std :: vector ', yadda yadda. – GManNickG

+0

Pourquoi pensez-vous qu'avec std :: vector vous n'avez aucun contrôle sur la durée de vie de l'objet? –

+0

La question n'est pas claire. Avez-vous le contrôle de la désaffectation ou confiez-vous cette responsabilité à une bibliothèque? Toutes les réponses d'avant cette modification ne répondent pas aux exigences modifiées. –

Répondre

7

Utilisation new avec un seul objet et new[] avec un tableau d'objets. Ainsi, par exemple:

 
int* x = new int; // Allocates single int 
int* y = new int[5]; // Allocates an array of integers 

*x = 10; // Assignment to single value 
y[0] = 8; // Assignment to element of the array 

Si tout ce que vous faites est l'attribution d'un tampon de mémoire, puis allouer un tableau de char comme dans:

 
int bufferlen = /* choose a buffer size somehow */ 
char* buffer = new char[bufferlen]; 
// now can refer to buffer[0] ... buffer[bufferlen-1] 

Cependant, en C++, vous devriez vraiment utiliser std::vector pour tableaux arbitraires, et vous devez utiliser std::string pour les tableaux de caractères qui doivent être interprétés ou utilisés comme chaînes.

Il n'y a aucune raison d'invoquer explicitement ::operator new ou ::operator new[] plutôt que d'utiliser la syntaxe ordinaire pour ces appels. Pour les types POD et primitifs (par exemple char), aucune initialisation n'aura lieu. Si vous avez besoin d'un tampon void*, utilisez simplement static_cast pour convertir char* en void*.

+2

L'OP ne parle pas de 'new int' et' new int [5] ', mais appelle spécifiquement les fonctions avec les noms donnés, par ex. 'void * p = opérateur new (50);' vs 'void * p = opérateur nouveau [] (50);'. –

+0

@Roger, merci. Cela n'a pas été précisé avant une modification ultérieure. –

+2

Votre mise à jour est légèrement fausse. Il y a une différence entre 'new int' et' new int() '(le dernier objet est garanti être initialisé à zéro), et de même pour tout type de POD. Un cas particulier fonctionne également pour new []: 'new int [5]()'. –

0

pour allouer de la mémoire à matrice/liste utiliser de nouvelles [] autre que celui utiliser de nouvelles ...

1

L'avantage des new C++ opérateurs sur C de malloc() et free() est que l'ancien lève une exception s'il n'y a pas assez de mémoire, plutôt que de retourner NULL. En ce qui concerne le choix de la nouvelle (taille) et de la nouvelle [] pour les tampons de caractères, je préconiserais ce dernier car il est moins susceptible de surprendre les gens maintenant le code plus tard, c'est-à-dire char* buf = new char[size] et delete[] buf. Les valeurs dans le tampon ne seront pas initialisées, et il n'y a aucune vérification de gamme - vous devez construire un bel objet C++ pour le faire pour vous, ou utiliser un objet existant tel que std::vector ou std::string.

1

Il est impossible de répondre à la question de façon judicieuse. Tout d'abord, il est dit que le programme 'nécessite' un bloc de mémoire non initialisée mais, à partir de l'exemple de code donné, il semble que le programme 'nécessite' un bloc de mémoire non initialisée et UNTYPED qui ne semble pas très C++ ou OO .

Deuxièmement, un vecteur std :: donne un contrôle unique et automatique sur un bloc de mémoire typée qui peut ou non changer de taille en fonction de son utilisation. Vous pouvez perdre ce contrôle si une instance de std :: vector est créée sur le tas et suivie avec des pointeurs bruts comme pour tout autre objet C ou C++ tel qu'un bloc de mémoire void *.

Troisièmement, quelle est l'utilisation prévue de ce bloc de mémoire? La réponse à cette question peut ou non dicter l'utilisation de l'opérateur new ou operator new []. Dans la conception de ce programme, existe-t-il une interprétation unique de ce bloc de mémoire? Quelle sémantique de propriété avez-vous besoin, le cas échéant? Etc, etc.

+0

Note: Ces questions ont été répondues lors d'une édition ultérieure. –

Questions connexes