web-dev-qa-db-fra.com

C ++ new int [0] - va-t-il allouer de la mémoire?

Une application de test simple:

cout << new int[0] << endl;

les sorties:

0x876c0b8

Donc, on dirait que ça marche. Que dit la norme à ce sujet? Est-il toujours légal "d'allouer" un bloc de mémoire vide?

224
anon

À partir de 5.3.4/7

Lorsque la valeur de l'expression dans direct-new-declarator est égale à zéro, la fonction d'allocation est appelée pour allouer un tableau sans éléments.

À partir de 3.7.3.1/2

L'effet de déréférencer un pointeur renvoyé sous la forme d'une demande de taille zéro est indéfini.

Également

Même si la taille de l'espace demandé [par new] est égale à zéro, la demande peut échouer.

Cela signifie que vous pouvez le faire, mais que vous ne pouvez pas légalement (de manière bien définie sur toutes les plates-formes) déréférencer la mémoire que vous obtenez - vous pouvez uniquement le transmettre à array delete - et vous devez le supprimer.

Voici une note de bas de page intéressante (c’est-à-dire qui ne constitue pas une partie normative de la norme, mais qui est incluse à des fins explicatives) jointe à la phrase du 3.7.3.1/2

[32. L'intention est d'avoir l'opérateur new () implémentable en appelant malloc () ou calloc (), afin que les règles soient sensiblement les mêmes. C++ diffère de C en nécessitant une requête zéro pour renvoyer un pointeur non nul.]

226
Faisal Vali

Oui, il est légal d'allouer un tableau de taille zéro comme celui-ci. Mais vous devez également le supprimer.

21
anon

Que dit la norme à ce sujet? Est-il toujours légal "d'allouer" un bloc de mémoire vide?

Chaque 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 augmentée de manière silencieuse, si vous demandez zéro octet).

Si vous allouez plus d'un de ces objets, vous constaterez qu'ils ont des adresses différentes.

15
ChrisW

Oui, il est tout à fait légal d’allouer un bloc de taille 0 Avec new. Vous ne pouvez tout simplement rien faire d’utile avec ce logiciel car il n’existe aucune donnée valide à votre disposition. int[0] = 5; Est illégal.

Cependant, je pense que la norme permet à des choses comme malloc(0) de renvoyer NULL.

Vous aurez toujours besoin de delete [] Quel que soit le pointeur que vous récupérez de l'allocation.

14
Evan Teran

Curieusement, C++ exige que l'opérateur new retourne un pointeur légitime même lorsque zéro octet est demandé. (Exiger ce comportement étrange simplifie les choses ailleurs dans le langage.)

J'ai trouvé Effective C++ Third Edition dit comme cela dans "Item 51: Respecter les conventions lors de l'écriture de new et delete".

1
shuaihanhungry