OVH Cloud OVH Cloud

delete []

39 réponses
Avatar
Jean-Marie Epitalon
Bonjour,

quelqu'un pourrait-il me dire à quoi sert les [] dans l'instruction delete
[] comme dans l'exemple suivant:

int * ma_table = new int[10];
...
delete [] ma_table;

Je me demande pourquoi on en a besoin car en langage C, quand on libère de
la mémoire, on passe un pointeur à la fonction free() et c'est tout....
Merci
Jean-Marie

10 réponses

1 2 3 4
Avatar
Marc Boyer
Le 20-11-2006, Jean-Marie Epitalon a écrit :
quelqu'un pourrait-il me dire à quoi sert les [] dans l'instruction delete
[] comme dans l'exemple suivant:

int * ma_table = new int[10];
...
delete [] ma_table;

Je me demande pourquoi on en a besoin car en langage C, quand on libère de
la mémoire, on passe un pointeur à la fonction free() et c'est tout....


Parce que le delete[] appelle les destructeurs de tous les
objets dans le tableau. Pour int, ça ne fait pas grand chose,
mais en général, c'est plus compliqué.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)

Avatar
Manuel Leclerc

Parce que le delete[] appelle les destructeurs de tous les
objets dans le tableau. Pour int, ça ne fait pas grand chose,
mais en général, c'est plus compliqué.


D'un autre côté, si delete[] peut faire ça, delete tout court
pourrait le faire aussi, non ?

--
This type of modern life
Is it for me?
This type of modern life
Is it for free?

Avatar
Marc Boyer
Le 20-11-2006, Manuel Leclerc a écrit :
Parce que le delete[] appelle les destructeurs de tous les
objets dans le tableau. Pour int, ça ne fait pas grand chose,
mais en général, c'est plus compliqué.


D'un autre côté, si delete[] peut faire ça, delete tout court
pourrait le faire aussi, non ?


J'imagine que oui, on pourrait considérer toute variable comme
un tableau de taille 1.
J'ai toujours imaginé qu'il devait y avoir un surcoût associé
au new[]/delete[] par rapport à new/delete, et que comme on
traque les surcouts en C++, on a offert les deux.
M'enfin bon, je miserais pas mon salaire sur cette hypothèse.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)


Avatar
Jean-Marc Bourguet
"Manuel Leclerc" writes:


Parce que le delete[] appelle les destructeurs de tous les
objets dans le tableau. Pour int, ça ne fait pas grand chose,
mais en général, c'est plus compliqué.


D'un autre côté, si delete[] peut faire ça, delete tout court
pourrait le faire aussi, non ?


Il faut liberer avec delete[] ce qui a ete alloue avec new[] comme il faut
liberer avec delete ce qui a ete libere avec new. On pourrait imaginer un
delete qui permette de faire les deux, mais
- on ne pourrait plus surcharger new[] et new independemment;
- tout ce qui est alloue avec new deviendrait plus gros pour stocker
l'information du nombre d'elements alloues.

A+

--
Jean-Marc


Avatar
Jean-Marc Desperrier
Jean-Marc Bourguet wrote:
Il faut liberer avec delete[] ce qui a ete alloue avec new[] comme il faut
liberer avec delete ce qui a ete libere avec new. On pourrait imaginer un
delete qui permette de faire les deux,


Justement la plupart des implémentations "pardonnent" cette erreur et
font ce qu'il faut même avec le mauvais appel, non ?

Avatar
Alain Gaillard

Justement la plupart des implémentations "pardonnent" cette erreur et
font ce qu'il faut même avec le mauvais appel, non ?


Souvent les implémentations se contentent d'invoquer les malloc et free
du C. Mais on ne peut pas compter sur ce que va faire une
implémentation. Et puis pour un même compîlateur, tu n'as aucune
garantie à ce niveau que la nouvelle version fera de même que l'ancienne.


--
Alain

Avatar
Jean-Marc Bourguet
Jean-Marc Desperrier writes:

Jean-Marc Bourguet wrote:
Il faut liberer avec delete[] ce qui a ete alloue avec new[] comme il faut
liberer avec delete ce qui a ete libere avec new. On pourrait imaginer un
delete qui permette de faire les deux,


Justement la plupart des implémentations "pardonnent" cette erreur et font
ce qu'il faut même avec le mauvais appel, non ?


* Je doute qu'il y ait des implémentations qui appellent les destructeurs
correctement quand on utilise delete plutôt que delete[].

* Dans le cas de new[] et delete[], le compilateur doit stocker le nombre
d'éléments alloués pour pouvoir faire ces appels. Le premier endroit qui
me vient à l'esprit, c'est d'allouer la taille d'un int (ou plus pour des
raisons d'alignement) en plus et de mettre ce nombre en tête de bloc.
Donc le compilateur dans le cas d'un appel à delete[] doit faire un
ajustement avant de passer le pointeur à operator delete[]. Ça ne
m'étonnerait pas que l'absence d'ajustement avec delete ne pardonne pas.
(Comme ce nombre est inutile dans le cas des POD, ça ne m'étonnerait pas
non plus qu'un compilateur optimise en le supprimant dans ce cas là,
auquel cas en effet l'appel à delete plutôt que delete[] pourrait passer
inapperçu jusqu'à l'ajout d'un destructeur ou l'implémentation d'une
autre politique d'allocation pour les tableaux...)

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


Avatar
Loïc Joly
Jean-Marc Bourguet wrote:

Il faut liberer avec delete[] ce qui a ete alloue avec new[] comme il
faut
liberer avec delete ce qui a ete libere avec new. On pourrait
imaginer un
delete qui permette de faire les deux,



Justement la plupart des implémentations "pardonnent" cette erreur et
font ce qu'il faut même avec le mauvais appel, non ?


J'ai eu un vrai programme qui plantait avec un compilo non expérimental
(visual C++6), parce qu'on faisait delete après avoir fait new[]. En
plus le plantage était dans un endroit sans aucuns rapports, toujours
différent, seule une revue du code a permis de voir le problème, et de
constater le lien entre celui-ci et le plantage.

--
Loïc


Avatar
Sylvain
Loïc Joly wrote on 20/11/2006 21:15:

J'ai eu un vrai programme qui plantait avec un compilo non expérimental
(visual C++6), parce qu'on faisait delete après avoir fait new[]. En
plus le plantage était dans un endroit sans aucuns rapports, toujours
différent, seule une revue du code a permis de voir le problème, et de
constater le lien entre celui-ci et le plantage.


la portion de code n'avait jamais été vérifiée en mode debug alors.
(en effet en mode release, le tas peut être corrumpu et péter n'importe
où après).

Sylvain.

Avatar
Loïc Joly
Loïc Joly wrote on 20/11/2006 21:15:


J'ai eu un vrai programme qui plantait avec un compilo non
expérimental (visual C++6), parce qu'on faisait delete après avoir
fait new[]. En plus le plantage était dans un endroit sans aucuns
rapports, toujours différent, seule une revue du code a permis de voir
le problème, et de constater le lien entre celui-ci et le plantage.



la portion de code n'avait jamais été vérifiée en mode debug alors.
(en effet en mode release, le tas peut être corrumpu et péter n'importe
où après).


Ca date d'il y a quelques années, je ne me souviens donc plus des
détails... Mais il me semble bien que ça posait aussi des problèmes en
mode débug.

--
Loïc


1 2 3 4