l'opérateur [] appliqué à un tableau ignore tout de la virtualité, son calcul d'offset (comme '++') n'utilise que la taille de son type donc A (soit 1 int).
C'est ce qui explique que, si je rajoute des destructeurs virtuels, un delete [] tab segfault ?
il y a en effet des chances que le delete du second élément mette la cata. (le "iterate_delete_item_from_array" fait un appel virtuel correct, mais le calcul de l'offset de l'élément suivant est mauvais).
Sylvain.
Mickaël Wolff wrote on 07/08/2008 22:26:
Sylvain SF a écrit :
l'opérateur [] appliqué à un tableau ignore tout de la virtualité,
son calcul d'offset (comme '++') n'utilise que la taille de son type
donc A (soit 1 int).
C'est ce qui explique que, si je rajoute des destructeurs virtuels, un
delete [] tab segfault ?
il y a en effet des chances que le delete du second élément mette la
cata. (le "iterate_delete_item_from_array" fait un appel virtuel
correct, mais le calcul de l'offset de l'élément suivant est mauvais).
l'opérateur [] appliqué à un tableau ignore tout de la virtualité, son calcul d'offset (comme '++') n'utilise que la taille de son type donc A (soit 1 int).
C'est ce qui explique que, si je rajoute des destructeurs virtuels, un delete [] tab segfault ?
il y a en effet des chances que le delete du second élément mette la cata. (le "iterate_delete_item_from_array" fait un appel virtuel correct, mais le calcul de l'offset de l'élément suivant est mauvais).
Sylvain.
Fabien LE LEZ
On Thu, 7 Aug 2008 08:38:00 -0700 (PDT), Sébastien M. :
Oui mais malheureusement on doit parfois utiliser des APIs mal faites qui nous obligent à faire ce genre de choses ( new[] à la place de vector ).
Uh ? Dans quel cas ?
Si tu as une fonction (dans une bibliothèque, typiquement écrite en C) de ce style : int f (char* ptr, size_t lng); tu peux écrire :
std::vector <char> buf (la_taille_voulue); f (&buf[0], buf.size());
Il me semble que l'usage de new[] est si rare qu'il justifie, à chaque usage, un commentaire indiquant pourquoi on n'a pas utilisé une autre solution.
On Thu, 7 Aug 2008 08:38:00 -0700 (PDT), Sébastien M. :
Oui mais malheureusement on doit parfois utiliser des APIs mal faites
qui nous obligent à faire ce genre de choses ( new[] à la place de
vector ).
Uh ? Dans quel cas ?
Si tu as une fonction (dans une bibliothèque, typiquement écrite en C)
de ce style :
int f (char* ptr, size_t lng);
tu peux écrire :
std::vector <char> buf (la_taille_voulue);
f (&buf[0], buf.size());
Il me semble que l'usage de new[] est si rare qu'il justifie, à chaque
usage, un commentaire indiquant pourquoi on n'a pas utilisé une autre
solution.
l'allocation A* tab = new B[4]; avec la boucle (int i=0; i<16; ++i) donnerait le même résultat et pas d'erreur d'accès hors buffer (or cas d'alignement particulier ou autre "indéfini").
l'opérateur [] appliqué à un tableau ignore tout de la virtualité, son calcul d'offset (comme '++') n'utilise que la taille de son type donc A (soit 1 int).
Ça explique ce qui se passe probablement dans l'implémentation (et c'est en effet la justification du comportement indéfini), mais pour l'utilisateur : l'arithmétique sur pointeurs (et donc l'indexation, qui est définie en termes d'arithmétique sur pointeurs) n'est défini qu'à l'intérieur d'un tableau, avec des pointeurs à des éléments du tableau (ou un au-delà de la fin du tableau). Et que si tu as un tableau de B, un A* ne pourrait jamais désigner un élément du tableau, parce que les éléments ne sont pas des A.
std::vector n'est pas obligeatoire (je n'utilise jamais 'cette' version) mais un tableau doit autant que faire ce peut conserver son type vrai.
std::vector se comporte plus ou moins comme un tableau classique à cet égard.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Aug 7, 9:52 pm, Sylvain SF <sylv...@boiteaspam.info> wrote:
Sébastien M. wrote on 07/08/2008 17:27:
>> Puis-je demander pour quelle raison on pourrait s'attendre
>> à un warning?
> C'est un comportement indéfini.
> Pour les compilateurs avec lesquels j'ai fait les tests, le
> programme affiche ceci :
> 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1
car A est un POD de taille "1" (en posant qu'un int à une
taille de une unité) et B un POD de 4 unités.
le new B[] alloue (et initialise) bien un tableau de POD de
taille 4, mais la boucle balaye un A[], en fait on affiche
(syntaxe abusive):
l'allocation A* tab = new B[4]; avec la boucle (int i=0; i<16;
++i) donnerait le même résultat et pas d'erreur d'accès hors
buffer (or cas d'alignement particulier ou autre "indéfini").
l'opérateur [] appliqué à un tableau ignore tout de la
virtualité, son calcul d'offset (comme '++') n'utilise que la
taille de son type donc A (soit 1 int).
Ça explique ce qui se passe probablement dans l'implémentation
(et c'est en effet la justification du comportement indéfini),
mais pour l'utilisateur : l'arithmétique sur pointeurs (et donc
l'indexation, qui est définie en termes d'arithmétique sur
pointeurs) n'est défini qu'à l'intérieur d'un tableau, avec des
pointeurs à des éléments du tableau (ou un au-delà de la fin du
tableau). Et que si tu as un tableau de B, un A* ne pourrait
jamais désigner un élément du tableau, parce que les éléments ne
sont pas des A.
std::vector n'est pas obligeatoire (je n'utilise jamais
'cette' version) mais un tableau doit autant que faire ce peut
conserver son type vrai.
std::vector se comporte plus ou moins comme un tableau classique
à cet égard.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
l'allocation A* tab = new B[4]; avec la boucle (int i=0; i<16; ++i) donnerait le même résultat et pas d'erreur d'accès hors buffer (or cas d'alignement particulier ou autre "indéfini").
l'opérateur [] appliqué à un tableau ignore tout de la virtualité, son calcul d'offset (comme '++') n'utilise que la taille de son type donc A (soit 1 int).
Ça explique ce qui se passe probablement dans l'implémentation (et c'est en effet la justification du comportement indéfini), mais pour l'utilisateur : l'arithmétique sur pointeurs (et donc l'indexation, qui est définie en termes d'arithmétique sur pointeurs) n'est défini qu'à l'intérieur d'un tableau, avec des pointeurs à des éléments du tableau (ou un au-delà de la fin du tableau). Et que si tu as un tableau de B, un A* ne pourrait jamais désigner un élément du tableau, parce que les éléments ne sont pas des A.
std::vector n'est pas obligeatoire (je n'utilise jamais 'cette' version) mais un tableau doit autant que faire ce peut conserver son type vrai.
std::vector se comporte plus ou moins comme un tableau classique à cet égard.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
James Kanze
On Aug 7, 10:26 pm, Mickaël Wolff wrote:
Sylvain SF a écrit :
> l'opérateur [] appliqué à un tableau ignore tout de la > virtualité, son calcul d'offset (comme '++') n'utilise que > la taille de son type donc A (soit 1 int).
C'est ce qui explique que, si je rajoute des destructeurs virtuels, un delete [] tab segfault ?
Surtout, ce qui l'explique, c'est que la norme dit que dans un delete[], si le type dynamique n'est pas le même que le type statique, c'est un comportement indéfini. (Mais la motivation est la même : il a besoin de l'arithmétique sur pointeurs, qui suppose que le compilateur connaissent la taille réele de l'objet.)
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Aug 7, 10:26 pm, Mickaël Wolff <mickael.wo...@laposte.net> wrote:
Sylvain SF a écrit :
> l'opérateur [] appliqué à un tableau ignore tout de la
> virtualité, son calcul d'offset (comme '++') n'utilise que
> la taille de son type donc A (soit 1 int).
C'est ce qui explique que, si je rajoute des destructeurs
virtuels, un delete [] tab segfault ?
Surtout, ce qui l'explique, c'est que la norme dit que dans un
delete[], si le type dynamique n'est pas le même que le type
statique, c'est un comportement indéfini. (Mais la motivation
est la même : il a besoin de l'arithmétique sur pointeurs, qui
suppose que le compilateur connaissent la taille réele de
l'objet.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
> l'opérateur [] appliqué à un tableau ignore tout de la > virtualité, son calcul d'offset (comme '++') n'utilise que > la taille de son type donc A (soit 1 int).
C'est ce qui explique que, si je rajoute des destructeurs virtuels, un delete [] tab segfault ?
Surtout, ce qui l'explique, c'est que la norme dit que dans un delete[], si le type dynamique n'est pas le même que le type statique, c'est un comportement indéfini. (Mais la motivation est la même : il a besoin de l'arithmétique sur pointeurs, qui suppose que le compilateur connaissent la taille réele de l'objet.)
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
James Kanze
On Aug 8, 4:46 am, Fabien LE LEZ wrote:
On Thu, 7 Aug 2008 08:38:00 -0700 (PDT), Sébastien M. :
[...]
Il me semble que l'usage de new[] est si rare qu'il justifie, à chaque usage, un commentaire indiquant pourquoi on n'a pas utilisé une autre solution.
Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à tous les niveaux (de l'implémentation des vecteur et des chaînes à l'époque avant la norme, jusqu'aux applications complètes), et je n'ai jamais eu la moindre occasion d'utiliser un new[].
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Aug 8, 4:46 am, Fabien LE LEZ <grams...@gramster.com> wrote:
On Thu, 7 Aug 2008 08:38:00 -0700 (PDT), Sébastien M. :
[...]
Il me semble que l'usage de new[] est si rare qu'il justifie,
à chaque usage, un commentaire indiquant pourquoi on n'a pas
utilisé une autre solution.
Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à
tous les niveaux (de l'implémentation des vecteur et des chaînes
à l'époque avant la norme, jusqu'aux applications complètes), et
je n'ai jamais eu la moindre occasion d'utiliser un new[].
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Thu, 7 Aug 2008 08:38:00 -0700 (PDT), Sébastien M. :
[...]
Il me semble que l'usage de new[] est si rare qu'il justifie, à chaque usage, un commentaire indiquant pourquoi on n'a pas utilisé une autre solution.
Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à tous les niveaux (de l'implémentation des vecteur et des chaînes à l'époque avant la norme, jusqu'aux applications complètes), et je n'ai jamais eu la moindre occasion d'utiliser un new[].
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sébastien M.
On 8 août, 04:46, Fabien LE LEZ wrote:
On Thu, 7 Aug 2008 08:38:00 -0700 (PDT), Sébastien M. :
>Oui mais malheureusement on doit parfois utiliser des APIs mal faites >qui nous obligent à faire ce genre de choses ( new[] à la place de >vector ).
Uh ? Dans quel cas ?
Dans cette API, on est sensé hérité d'une classe mère pour ajouté des comportement.
Il y a des donnée 'protected' de la classe mère qui doivent être initialisées par les classes filles dont un tableau d'objet. Cette nouvelle classe doit faire le new sinon la classe mère n'a pas ce quelle veut ... (évidement on n'a pas accès au code de la classe mère )
Enfin ... le coté positif c'est que je ne vais bientôt plus travailler sur ce truc :-D
-- Sébastien
On 8 août, 04:46, Fabien LE LEZ <grams...@gramster.com> wrote:
On Thu, 7 Aug 2008 08:38:00 -0700 (PDT), Sébastien M. :
>Oui mais malheureusement on doit parfois utiliser des APIs mal faites
>qui nous obligent à faire ce genre de choses ( new[] à la place de
>vector ).
Uh ? Dans quel cas ?
Dans cette API, on est sensé hérité d'une classe mère pour ajouté des
comportement.
Il y a des donnée 'protected' de la classe mère qui doivent être
initialisées par les classes filles dont un tableau d'objet. Cette
nouvelle classe doit faire le new sinon la classe mère n'a pas ce
quelle veut ... (évidement on n'a pas accès au code de la classe mère )
Enfin ... le coté positif c'est que je ne vais bientôt plus travailler
sur ce truc :-D
On Thu, 7 Aug 2008 08:38:00 -0700 (PDT), Sébastien M. :
>Oui mais malheureusement on doit parfois utiliser des APIs mal faites >qui nous obligent à faire ce genre de choses ( new[] à la place de >vector ).
Uh ? Dans quel cas ?
Dans cette API, on est sensé hérité d'une classe mère pour ajouté des comportement.
Il y a des donnée 'protected' de la classe mère qui doivent être initialisées par les classes filles dont un tableau d'objet. Cette nouvelle classe doit faire le new sinon la classe mère n'a pas ce quelle veut ... (évidement on n'a pas accès au code de la classe mère )
Enfin ... le coté positif c'est que je ne vais bientôt plus travailler sur ce truc :-D
-- Sébastien
Sébastien M.
> Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à tous les niveaux (de l'implémentation des vecteur et des chaînes à l'époque avant la norme, jusqu'aux applications complètes), et je n'ai jamais eu la moindre occasion d'utiliser un new[].
Sauf si on utilise un "allocator" développé par quelqu'un d'autre je pense qu'on doit avoir au moins un new dans le programme si on implémente soit même les classes de base :-D
Après je suis d'accord qu'on ne doit pas avoir de "new" si on utilise la STL et pas plus d'un "new" si on implémente tout depuis le début.
-- Sébastien
>
Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à
tous les niveaux (de l'implémentation des vecteur et des chaînes
à l'époque avant la norme, jusqu'aux applications complètes), et
je n'ai jamais eu la moindre occasion d'utiliser un new[].
Sauf si on utilise un "allocator" développé par quelqu'un d'autre je
pense qu'on doit avoir au moins un new dans le programme si on
implémente soit même les classes de base :-D
Après je suis d'accord qu'on ne doit pas avoir de "new" si on utilise
la STL et pas plus d'un "new" si on implémente tout depuis le début.
> Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à tous les niveaux (de l'implémentation des vecteur et des chaînes à l'époque avant la norme, jusqu'aux applications complètes), et je n'ai jamais eu la moindre occasion d'utiliser un new[].
Sauf si on utilise un "allocator" développé par quelqu'un d'autre je pense qu'on doit avoir au moins un new dans le programme si on implémente soit même les classes de base :-D
Après je suis d'accord qu'on ne doit pas avoir de "new" si on utilise la STL et pas plus d'un "new" si on implémente tout depuis le début.
-- Sébastien
Fabien LE LEZ
On Fri, 8 Aug 2008 02:16:59 -0700 (PDT), Sébastien M. :
Dans cette API, on est sensé hérité d'une classe mère pour ajouté des
Par pitié, relis ta prose avant de poster !
Il y a des donnée 'protected' de la classe mère qui doivent être initialisées par les classes filles dont un tableau d'objet.
Gnii ? J'ai l'impression que c'est un bon candidat pour <http://thedailywtf.com/> :-/
Enfin ... le coté positif c'est que je ne vais bientôt plus travailler sur ce truc :-D
J'imagine que ça va beaucoup te soulager.
On Fri, 8 Aug 2008 02:16:59 -0700 (PDT), Sébastien M.
<plouf79@yahoo.fr>:
Dans cette API, on est sensé hérité d'une classe mère pour ajouté des
Par pitié, relis ta prose avant de poster !
Il y a des donnée 'protected' de la classe mère qui doivent être
initialisées par les classes filles dont un tableau d'objet.
Gnii ? J'ai l'impression que c'est un bon candidat pour
<http://thedailywtf.com/> :-/
Enfin ... le coté positif c'est que je ne vais bientôt plus travailler
sur ce truc :-D
> >Dans cette API, on est sensé hérité d'une classe mère pour ajout é des
Par pitié, relis ta prose avant de poster !
oups :-( désolé.
>Il y a des donnée 'protected' de la classe mère qui doivent être >initialisées par les classes filles dont un tableau d'objet.
Gnii ? J'ai l'impression que c'est un bon candidat pour <http://thedailywtf.com/> :-/
oui, je pense qu'on pourrait même faire une série d'articles.
>Enfin ... le coté positif c'est que je ne vais bientôt plus travaill er >sur ce truc :-D
J'imagine que ça va beaucoup te soulager.
oh oui.
Jean-Marc Bourguet
Sébastien M. writes:
> > Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à > tous les niveaux (de l'implémentation des vecteur et des chaînes > à l'époque avant la norme, jusqu'aux applications complètes), et > je n'ai jamais eu la moindre occasion d'utiliser un new[]. >
Sauf si on utilise un "allocator" développé par quelqu'un d'autre je pense qu'on doit avoir au moins un new dans le programme si on implémente soit même les classes de base :-D
Il a ecrit new[] pas new.
(Je dois en avoir ecrit mais je ne me souviens pas d'occasions ou vector<> ou une classe similaire n'aurait pas ete en fait une meilleure solution).
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Sébastien M. <plouf79@yahoo.fr> writes:
>
> Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à
> tous les niveaux (de l'implémentation des vecteur et des chaînes
> à l'époque avant la norme, jusqu'aux applications complètes), et
> je n'ai jamais eu la moindre occasion d'utiliser un new[].
>
Sauf si on utilise un "allocator" développé par quelqu'un d'autre je
pense qu'on doit avoir au moins un new dans le programme si on
implémente soit même les classes de base :-D
Il a ecrit new[] pas new.
(Je dois en avoir ecrit mais je ne me souviens pas d'occasions ou vector<>
ou une classe similaire n'aurait pas ete en fait une meilleure solution).
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
> > Pour confirmer : je pratique le C++ depuis prèsque 20 ans, à > tous les niveaux (de l'implémentation des vecteur et des chaînes > à l'époque avant la norme, jusqu'aux applications complètes), et > je n'ai jamais eu la moindre occasion d'utiliser un new[]. >
Sauf si on utilise un "allocator" développé par quelqu'un d'autre je pense qu'on doit avoir au moins un new dans le programme si on implémente soit même les classes de base :-D
Il a ecrit new[] pas new.
(Je dois en avoir ecrit mais je ne me souviens pas d'occasions ou vector<> ou une classe similaire n'aurait pas ete en fait une meilleure solution).
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org