C ++ new int [0] - il va allouer de la mémoire?
-
23-08-2019 - |
Question
Une application simple test:
cout << new int[0] << endl;
sorties:
0x876c0b8
Il semble donc que cela fonctionne. Que dit la norme à ce sujet? Est-il toujours légal de « allouer » bloc vide de la mémoire?
La solution
De 5.3.4 / 7
Lorsque la valeur de l'expression dans une nouvelle directe declarator est égal à zéro, la fonction de répartition est appelée à allouer un tableau avec aucun élément.
De 3.7.3.1/2
L'effet de déréférencement d'un pointeur est retourné en tant que demande pour une taille de zéro est indéfini.
Aussi
Même si la taille de l'espace demandé [par le nouveau] est égal à zéro, la demande peut échouer.
Cela signifie que vous pouvez le faire, mais vous ne pouvez pas légalement (d'une manière bien définie sur toutes les plateformes) déréférencer la mémoire que vous obtenez - vous ne pouvez passer à un tableau supprimer -. Et vous devez le supprimer
Voici un pied-note intéressante (i.e. pas une partie normative de la norme, mais inclus à des fins expositoires) rattachées à la peine de 3.7.3.1/2
[32. Le but est d'avoir opérateur nouveau () implémentable en appelant malloc () ou calloc (), de sorte que les règles sont sensiblement les mêmes. C ++ diffère de C en nécessitant une demande de zéro à renvoyer un pointeur non nul.]
Autres conseils
Oui, il est légal d'allouer un tableau de taille zéro comme ça. Mais vous devez aussi le supprimer.
Que dit la norme à ce sujet? Est-il toujours légal de « allouer » bloc vide de la mémoire?
Chaque objet a une identité unique, à savoir une adresse unique, ce qui implique une longueur non nulle (le montant réel de la mémoire sera silencieusement augmentée, si vous demandez zéro octets).
Si vous avez alloué plus d'un de ces objets, vous trouveriez qu'ils ont des adresses différentes.
Oui, il est tout à fait légal d'allouer un bloc de taille 0
avec new
. Vous ne pouvez simplement pas faire quelque chose d'utile car il n'y a pas de données valides pour que vous puissiez accéder. int[0] = 5;
est illégale.
Cependant, je crois que la norme permet des choses comme malloc(0)
de revenir NULL
.
Vous aurez toujours besoin de delete []
quel que soit le pointeur que vous revenez de l'allocation ainsi.
Chose curieuse, C ++ exige que l'opérateur new retour un pointeur légitime même lorsque zéro octets sont demandés. (Nécessitant ce-sondage impair comportement simplifie les choses ailleurs dans la langue.)
J'ai trouvé efficace C ++ Troisième édition dit comme ça dans "Point 51: respecter la convention lors de l'écriture nouvelle et supprimer".