Une application de test simple:
cout << new int[0] << endl;
les sorties:
0x876c0b8
Il semble donc que cela fonctionne. Que dit la norme à ce sujet? Est-il toujours légal "d'allouer" un bloc de mémoire vide?
Une application de test simple:
cout << new int[0] << endl;
les sorties:
0x876c0b8
Il semble donc que cela fonctionne. Que dit la norme à ce sujet? Est-il toujours légal "d'allouer" un bloc de mémoire vide?
Réponses:
À partir du 5.3.4 / 7
À partir du 3.7.3.1/2
Aussi
Cela signifie que vous pouvez le faire, mais vous ne pouvez pas légalement (d'une manière bien définie sur toutes les plates-formes) déréférencer la mémoire que vous obtenez - vous ne pouvez la transmettre qu'à la suppression de tableaux - et vous devez la supprimer.
Voici une note de bas de page intéressante (c'est-à-dire pas une partie normative de la norme, mais incluse à des fins d'exposé) attachée à la phrase du 3.7.3.1/2
la source
new[]
avec undelete[]
- quelle que soit la taille. En particulier, lorsque vous appelez,new[i]
vous avez besoin d'un peu plus de mémoire que celle que vous essayez d'allouer afin de stocker la taille du tableau (qui sera ensuite utiliséedelete[]
lors de la désallocation)Oui, il est légal d'allouer un tableau de taille nulle comme celui-ci. Mais vous devez également le supprimer.
la source
int ar[0];
c'est illégal pourquoi est nouveau OK?sizeof (type)
on ne devrait jamais retourner zéro. Voir par exemple: stackoverflow.com/questions/2632021/can-sizeof-return-0-zeroChaque objet a une identité unique, c'est-à-dire une adresse unique, ce qui implique une longueur non nulle (la quantité réelle de mémoire sera silencieusement augmentée, si vous demandez zéro octet).
Si vous avez alloué plusieurs de ces objets, vous constaterez qu'ils ont des adresses différentes.
la source
operator []
stocke également la taille du tableau quelque part (voir isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-array ). Donc, si l'implémentation alloue le nombre d'octets avec les données, elle pourrait simplement allouer le nombre d'octets et 0 octet pour les données, en renvoyant le pointeur un avant-dernier.operator new[]
doivent renvoyer différents pointeurs. BTW, lenew expression
a quelques règles supplémentaires (5.3.4). Je n'ai trouvé aucun indicenew
qu'avec la taille 0 est réellement nécessaire pour allouer quoi que ce soit. Désolé, j'ai voté contre parce que je trouve que votre réponse ne répond pas aux questions, mais fournit des déclarations controversées.new[]
implémentation de renvoyer des adresses dans une plage où il n'y a pas de mémoire dynamique mappée, donc n'utilisant pas vraiment de mémoire (tout en utilisant l'espace d'adressage)while(!exitRequested) { char *p = new char[0]; delete [] p; }
boucle sans recycler les pointeurs s'effondrerait avant de manquer d'espace d'adressage, mais sur une plate-forme avec des pointeurs 32 bits, ce serait un hypothèse beaucoup moins raisonnable.Oui, il est tout à fait légal d'allouer un
0
bloc de taille avecnew
. Vous ne pouvez tout simplement rien faire d'utile car il n'y a pas de données valides auxquelles vous pouvez accéder.int[0] = 5;
est illégal.Cependant, je crois que la norme permet des choses comme
malloc(0)
le retourNULL
.Vous aurez également besoin du
delete []
pointeur que vous récupérez de l'allocation.la source
J'ai trouvé que la troisième édition efficace de C ++ disait comme ceci dans "Article 51: Adhérer à la convention lors de l'écriture de nouveaux et supprimer".
la source
Je vous garantis que le nouvel int [0] vous coûte plus d'espace depuis que je l'ai testé.
Par exemple, l'utilisation de la mémoire de
est significativement plus petit que
L'utilisation de la mémoire du deuxième extrait de code moins celle du premier extrait de code est la mémoire utilisée pour les nombreux nouveaux int [0].
la source