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
Lorsque la valeur de l'expression dans un déclarant direct nouveau est nulle, la fonction d'allocation est appelée pour allouer un tableau sans éléments.
À partir du 3.7.3.1/2
L'effet de déréférencer un pointeur renvoyé comme une demande de taille nulle n'est pas défini.
Aussi
Même si la taille de l'espace demandé [par nouveau] est nulle, 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 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
[32. L'intention est d'avoir l'opérateur new () implémentable en appelant malloc () ou calloc (), donc les règles sont sensiblement les mêmes. C ++ diffère de C en exigeant une demande nulle pour renvoyer un pointeur non nul.]
new[]
avec un delete[]
- 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ée delete[]
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.
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-zero
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 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.
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, le new expression
a quelques règles supplémentaires (5.3.4). Je n'ai trouvé aucun indice new
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 avec new
. 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 retour NULL
.
Vous aurez également besoin du delete []
pointeur que vous récupérez de l'allocation.
Curieusement, C ++ nécessite que l'opérateur new retourne un pointeur légitime même lorsque zéro octet est demandé. (Exiger ce comportement à consonance étrange simplifie les choses ailleurs dans la langue.)
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".
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
int **arr = new int*[1000000000];
est significativement plus petit que
int **arr = new int*[1000000000];
for(int i =0; i < 1000000000; i++) {
arr[i]=new int[0];
}
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].