OVH Cloud OVH Cloud

new A[0]

10 réponses
Avatar
Gilles Desforges
Bonjour,

A-t-on le droit de faire un new A[0] ?

J'ai un crash avec le code suivant :

class A
{
public:
virtual ~A() {}
};

int main()
{
A* a = new A[0];
delete[] a;

return 0;
}

NB: Si j'enlève le destructeur virtuel, je n'ai plus de crash...

--
Gilles.

10 réponses

Avatar
Thomas Parle
"Gilles Desforges" a écrit dans le message de
news: bq4om3$6b8$
Bonjour,

A-t-on le droit de faire un new A[0] ?


Oui, même si ça me parait un peu inutile.

NB: Si j'enlève le destructeur virtuel, je n'ai plus de crash...


je pense que c'est parce que le destructeur étant virtuel, il va essayer
d'aller chercher un objet A pour appeler son destructeur. Or, la taille de
ton tableau est de 0, il n'y a donc pas d'objet A, d'où l'erreur.

Avatar
DINH Viêt Hoà

"Gilles Desforges" a écrit dans le message de
news: bq4om3$6b8$
Bonjour,

A-t-on le droit de faire un new A[0] ?


Oui, même si ça me parait un peu inutile.


dans le cas où on a une allocation d'un nombre d'objets déterminé à
l'exécution.

t = new A[i];

NB: Si j'enlève le destructeur virtuel, je n'ai plus de crash...


je pense que c'est parce que le destructeur étant virtuel, il va essayer
d'aller chercher un objet A pour appeler son destructeur. Or, la taille de
ton tableau est de 0, il n'y a donc pas d'objet A, d'où l'erreur.


par contre, l'explication me convain(c/t) peu.

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan


Avatar
Gabriel Dos Reis
Loïc Joly writes:

| Ca peut ce comprendre, si on pense à toute les compliquations que ça
| apporterait (et au peut que ça apporterait), ainsi, aujourd'hui :

int n = 0;
new A[n];

est bien formé.

-- Gaby
Avatar
Loïc Joly
Gilles Desforges wrote:

Bonjour,

A-t-on le droit de faire un new A[0] ?


Non. Extrait du standard (8.3.4) :
In a declarationT D where D has the form D1 [constantexpressionopt] and
the type of the identifier in the declarationT D1 is
deriveddeclaratortypelist T,” then the type of the identifier of D is an
array type. T is called the array element type; this type shall not be a
reference type, the (possibly cvqualified) type void, a function type or
an abstract class type. If the constantexpression (5.19) is present, it
shall be an integral constant expression and its value shall be
greater than zero.

Ca peut ce comprendre, si on pense à toute les compliquations que ça
apporterait (et au peut que ça apporterait), ainsi, aujourd'hui :

- Un tableau de taille N possède N éléments, numérotés de 0 à N-1 -> Bug
si N == 0

- Quelle serait la taille d'un tableau de 0 éléments ? 0 ? Non, car tout
objet a une taille non nulle (pour que l'arithmétique de pointeurs
marche), autre chose que 0 ? Non, car on a comme égalité que
sizeof(tableau) == sizeof(element)*nombreElements.


DINH V. Hoa wrote:
dans le cas où on a une allocation d'un nombre d'objets déterminé à
l'exécution.

t = new A[i];


Dans ce cas, il faut de toute façon vérifier la saisie de l'utilisateur,
qui pourrait très bien avoir entré "-14", "iznogood" ou "". Je ne suis
pas persuadé que ne pas avoir à tester pour la valeur 0 soit d'un gain
important.

--
Loïc

Avatar
DINH Viêt Hoà

Loïc Joly writes:

| Ca peut ce comprendre, si on pense à toute les compliquations que ça
| apporterait (et au peut que ça apporterait), ainsi, aujourd'hui :

int n = 0;
new A[n];

est bien formé.


que veux-tu dire par là ?

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan

Avatar
Loïc Joly
Gabriel Dos Reis wrote:
Loïc Joly writes:

| Ca peut ce comprendre, si on pense à toute les compliquations que ça
| apporterait (et au peut que ça apporterait), ainsi, aujourd'hui :

int n = 0;
new A[n];

est bien formé.


Effectivement, je viens de lire (5.3.4):
When the value of the expression in a directnewdeclarator is zero, the
allocation function is called to allocate an array with no elements. The
pointer returned by the newexpression is nonnull.
[Note: If the library allocation function is called, the pointer
returned is distinct from the pointer to any other object. ]

Ce que j'avais lu précédemment était pour la déclaration d'un type (on
ne peut pas déclarer de variables "a" de forme "A a[0]"), ce qui ne
s'applique pas dans le post initial, ou l'on parle d'une expression
d'allocation dynamiquement de taille nulle.

Du coup, ma réponse n'explique pas l'erreur rencontrée par l'OP, et j'ai
du mal à voir d'où vient le traitement de faveur dont bénéficie un "new
A[0]" dans la norme par rapport à un "A a[0]".

--
Loïc

Avatar
DINH Viêt Hoà

Effectivement, je viens de lire (5.3.4):
When the value of the expression in a directnewdeclarator is zero, the
allocation function is called to allocate an array with no elements. The
pointer returned by the newexpression is nonnull.
[Note: If the library allocation function is called, the pointer
returned is distinct from the pointer to any other object. ]


auriez vous des pointeurs pour avoir un draft assez récent de la norme
du C++ ou quelque chose d'équivalent ?

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan

Avatar
Loïc Joly
DINH Viêt Hoà wrote:


Effectivement, je viens de lire (5.3.4):
When the value of the expression in a directnewdeclarator is zero, the
allocation function is called to allocate an array with no elements. The
pointer returned by the newexpression is nonnull.
[Note: If the library allocation function is called, the pointer
returned is distinct from the pointer to any other object. ]



auriez vous des pointeurs pour avoir un draft assez récent de la norme
du C++ ou quelque chose d'équivalent ?


Une recherche dans google avec "standard c++ draft 1996" donne des
résultats, mais ce n'est que le draft 1996, et non pas la norme elle
même. Je ne sais pas si les différences sont nombreuses ou pas.

Pour ma parte, j'ai acheté le standard en ligne sur le site de l'IOS
pour la norme 98 environ 18$.
http://webstore.ansi.org/ansidocstore/product.asp?sku=INCITS%2FISO%2FIEC+14882%2D1998

J'ai entendu dire, si tu aimes la lecture sur papier, qu'un livre allait
bientôt sortir avec le contenu du standard. Je n'ai aucune idée du prix.

--
Loïc


Avatar
kanze
Loïc Joly wrote in message
news:<bq61mg$tou$...

Gabriel Dos Reis wrote:
Loïc Joly writes:

| Ca peut ce comprendre, si on pense à toute les compliquations que
| ça apporterait (et au peut que ça apporterait), ainsi, aujourd'hui
| :

int n = 0;
new A[n];

est bien formé.


Effectivement, je viens de lire (5.3.4):

When the value of the expression in a directnewdeclarator is zero, the
allocation function is called to allocate an array with no
elements. The pointer returned by the newexpression is nonnull.
[Note: If the library allocation function is called, the pointer
returned is distinct from the pointer to any other object. ]

Ce que j'avais lu précédemment était pour la déclaration d'un type (on
ne peut pas déclarer de variables "a" de forme "A a[0]"), ce qui ne
s'applique pas dans le post initial, ou l'on parle d'une expression
d'allocation dynamiquement de taille nulle.

Du coup, ma réponse n'explique pas l'erreur rencontrée par l'OP,


La réponse, c'est que s'il a bien fait delete[], et non delete, il y a
une erreur dans son compilateur.

et j'ai du mal à voir d'où vient le traitement de faveur dont
bénéficie un "new A[0]" dans la norme par rapport à un "A a[0]".


C'est le même traitement de faveur qui permet une expression arbitraire
dans l'expression new, mais qui exige une constante dans la définition.
La contexte n'est pas la même ; les règles ne sont pas les même non
plus.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Gilles Desforges
Merci à tous.