Bonjour à tous,
Cela peut être aussi rendu plus ou moins stable grâce aux bibliothèques de débogage qui surchargent les allocations et suppressions en mode #ifdef DEBUG et vont se charger de... faire planter le programme le plus souvent et le plus tôt possible !
Exemple de pratiques de ces bibliothèques :
- remplissage et altération des données entre la déclaration et l'allocation, ainsi qu'à la suppression (vous avez peut-être vu dans votre débogueur des 0xfeed, 0xcdcd...). Cela évite d'utiliser des pointeurs avant qu'ils soient alloués et après leur destruction.
- entourer des tableaux par des "watchdogs", qui sont testés à la destruction de celui-ci pour vérifier que vous n'avez pas débordé d'un côté ou de l'autre.
- comptage des allocations et suppressions, vérifications en fin de programme de l'absence de fuites de mémoire.
On peut aussi rentre le code plus facile à écrire et à lire grâce à des classes templates qui encapsulent la construction et la destruction du pointeur.
On est souvent confronté à ce genre de situations :
1 2 3 4 5 6 7 8 9 10 11 12
| A a* = new A();
a->Foo();
/* ... plein de code ... */
// code rajouté par mise à jour
if( condition )
return;
/* ... plein de code ... */
a->Foo2();
delete a; |
Ici on est en présence d'une fuite de mémoire, c'est un peu grossier mais le principe à retenir c'est que c'est la complexité de l'arbre des possible qui peut rendre la mise en évidence de bugs de pointeurs.
De plus si on commence à avoir une pagaille de variables, il devient difficile et/ou lourdingue de tout libérer proprement et de suivre la ligne de vie de chacune d'entre elles.
On peut remplacer par :
CPointeur<A> a = new A();
où CPointeur se charge de détruire le pointeur correctement lorsqu'il devient hors de portée.
Ces classes et bibliothèques sont souvent fournies avec l'outil de développement, mais rares savent l'utiliser, qu'elles existent ou comprennent leur intérêt et se penchent quelques instants dessus.
Quelques "best practices" et stratégies aussi évitent bien des erreurs, comme les assertions (toujours dans l'idée d'anticiper le plantage) qui font qu'on peut utiliser les pointeurs "à sec" ou avec des pratiques se sécurité et une méthode tout le long du programme, qui n'est pas une perte de temps bien au contraire !
La mauvaise réputation des pointeurs vient en grande partie des premiers jours du C++ où les éditeurs et les bibliothèques ne faisaient pas grand chose pour faciliter leur utilisation.

Envoyé par
Elendil_BzH
Ah ouais j'avais oublié ça . Pourtant ça marche chez moi avec g++ 3.3.3, peut-être qu'il le fait tout seul.
Dans ton exemple, ça marche parce que l'adresse désignée par le pointeur est marquée comme libre mais par souci d'économie de temps, le programme ne modifie pas le contenu de l'adresse après suppression (comme tout programme le fait en mode RELEASE). En mode DEBUG, certaines bibliothèques font remplacer un simple delete par un :
delete p; memset(p, "0xcd", sizeof(p));
(ou équivalent, c'est le principe qui compte)
Dans ce cas, ton programme aurait planté (access violation) et tu aurais détecté ton erreur tout de suite. 
Enfin voilà, il y aurait beaucoup à dire mais en conclusion, le C++ permet de faire un peu ce qu'on veut avec la mémoire, c'est un jouet "pour les grands" donc c'est normal que cela comporte quelques risques et que cela nécessite une certaine maîtrise pour fonctionner correctement sans surprises, l'un ne va pas sans l'autre.
Partager