Qu'est ce qui peut faire planter un new ? - C++ - Programmation
Marsh Posté le 15-03-2004 à 18:34:16
ReplyMarsh Posté le 15-03-2004 à 18:52:40
En général, c'est une corruption des structures internes de l'allocateur mémoire. Double free/delete, ecriture en dehors des zones mémoires allouées etc...
Il y a des outils qui servent à trouver ce genre de problèmes. Des trucs comme valgrind sous Linux ou Purify sous Windows.
Marsh Posté le 15-03-2004 à 18:54:53
Kristoph a écrit : En général, c'est une corruption des structures internes de l'allocateur mémoire. Double free/delete, ecriture en dehors des zones mémoires allouées etc... |
Merci pour l'info
Cette corruption peut elle survenir à cause d'autres variables mal désallouées ou non-désalouées un peu avant dans le code ?
Marsh Posté le 15-03-2004 à 19:01:26
Une variable non désallouée ne crée pas ce genre de problèmes en général.
Marsh Posté le 15-03-2004 à 20:50:22
une delete sur un null n'a pas d'effet. Par contre et d'une manière générale, il faut tester si != null après chaque new...
Marsh Posté le 15-03-2004 à 20:52:40
JagStang a écrit : une delete sur un null n'a pas d'effet. Par contre et d'une manière générale, il faut tester si != null après chaque new... |
Il vaut mieux activer les exceptions plustot. Le temps ou il fallait tester les valeur de retour de chaque fonction succeptible d'échouer est passé et c'est tant mieux.
Marsh Posté le 15-03-2004 à 20:55:18
oui une bonne gestion d'exception est bien mieux. Mais il ne vaut mieux pas trop s'appuyer dessus quand c'est pas nécessaire.
Je te rassure, je suis du même avis que toi.
Marsh Posté le 15-03-2004 à 21:21:59
leFab a écrit : |
souvent en C, c'est a cause d'une mauvaise ecriture sur la pile, a l'adresse de retour de la fonction en cours.
A+,
Marsh Posté le 15-03-2004 à 21:24:40
Et il y a des causes connues de ce genre de pb ? En gros, que puis je faire pour y rémédier ?
Marsh Posté le 16-03-2004 à 00:52:30
Verifier que tu as pas ecrit en dehors des structures que tu as alloué.
Une autre cause a ce type de pb que j'ai vu (en C++ sous unix), c'est le fait d'utiliser des librairies compilees avec un compilo different de celui utilise pour compiler son code, et de voir le linker s'emmeler les pinceaux pour appeller le bon runtime (celui de la librairie etant different de celui du code ecrit). Bon, ca, par contre, ca se solutionne.
A+,
Marsh Posté le 16-03-2004 à 11:36:08
ouai enfin deja faire un new int[8] lol
...
si tu veux savoir si t as plus de place au moment de l allocation tu peut toujours faire un truc du style
void mo_new_handler_que_jaime(){
cerr<<" suite a une greve de memoire l'allocation ne peut avoir lieu" << endl;
exit(1);
}
au debut de ton main
set_new_handler(mo_new_handler_que_jaime)
en prenant soin d include new
pis j espere que tu fait bien un delete []tab;
et pas un delete tab pour toutes tes array..
et quand tu dis qua ca plante ca fait quoi exactement.
FK
Marsh Posté le 16-03-2004 à 12:04:35
frenchkiss a écrit : ouai enfin deja faire un new int[8] lol |
ouai enfin deja faire un new int[8] lol
?? Je ne comprends pas. Tu n'arrives pas à imaginer de cas d'allocation dynamique où tu puisses avoir besoin d'allouer dynamiquement 8 int ?
Ce que tu me dis là (le coup du handler) ne permet pas de savoir si je manque de place, et de toute façon, si je manque de place au moment de l'allocation, le new renvoie NULL, mais ne fait pas planter le prog.
Pour m'assurer que j'avais bien assez de mémoire au moment de l'allocation, je fais un new int[400] juste au dessus (c'est bourrin mais ça à l'avantage d'être rapide à mettre en place comme test), et ça passait à chaque fois.
Le message d'erreur est un truc du style "DAMAGE after normal block (#363)..." bref, rien de bien explicite, comme d'habitude.
Faire ou non des delete correct n'a à priori pas de rapport avec ce pb.
Marsh Posté le 16-03-2004 à 12:28:37
>> Le message d'erreur est un truc du style "DAMAGE after normal block (#363)..." bref, rien de bien explicite,
Tres explicite, au contraire. C'est quoi le bloc qui declenche cette erreur?
A+,
Marsh Posté le 16-03-2004 à 12:57:12
>Ce que tu me dis là (le coup du handler) ne permet pas de savoir si je manque de place,
ben si justement..
quand il n'y a plus diplace si le pointeur sur cette fonction est non nul alors elle est aplelle ...
quand a l'erreur , ben elle est qd meme pas banale donc d'autant plus utile.
et non , j arrive pas a imaginer une appli avec un new int[8] qqd part . ( 8 c'est pas vraiment dynamique)
>Faire ou non des delete correct n'a à priori pas de rapport avec ce pb.
... nan t as raison , apres tout pourquoi on s embete a faire des delete ..
Marsh Posté le 16-03-2004 à 13:22:44
Au contraire, confondre un appel a "delete" avec un appel a "delete []" peux causer des corruptions mémoire.
Marsh Posté le 16-03-2004 à 13:32:34
frenchkiss a écrit : >Ce que tu me dis là (le coup du handler) ne permet pas de savoir si je manque de place, |
Ben si c'est dynamique (j'ai juste mis 8 parce que dans le cas précis où ça plante, la variable que je passe dans le tableau vaut 8, je pensais que tt le monde aurait compris ça )
Pour le coup des delete, évidemment qu'on désalloue les tableaux avec delete[], mais ça c'est qd même la base des bases (merci de me le rappeler mais bon, j'ai qd même pas mal d'EXP en prog). Mais ce que je dis, c'est qu'à priori, dans le cas particulier du pb que j'ai rencontré il n'est PAS corrélé avec un truc mal désalloué (le pb survient avant l'appel explicite à tout delete).
Marsh Posté le 16-03-2004 à 14:09:18
De toute facon, tant que tu donneras aussi peu de contexte, c'est sur qu'on resoudra pas ton pb.
A+,
Marsh Posté le 16-03-2004 à 14:10:19
c sur..
d ou vient le 8
qu est ce que tu mets dans ton tab..
tu chausses du combien..
Marsh Posté le 16-03-2004 à 14:21:42
frenchkiss a écrit : c sur.. |
Le 8, c'est une variable qui vaut 8, peu importe d'où ça vient non ?
Le tab, ce que je mets dedans n'est pas important puisque le plantage survient avant que je mette quoi que ce soit dedans : il survient au moment de l'allocation.
gilou> je ne peux répondre à ta question, puisque l'erreur est désormais différente, même si elle arrive au même endroit : maintenant, l'allocation de ce tableau me renvoie un pointeur NULL. Alors que la mémoire est très loin d'être pleine.
Pour le contexte, quel genre d'info particulière veux tu (le code qu'il y a au dessus est assez long -> c'est un algo de calcul d'enveloppe convexe 3D si tu vois ce que c'est).
Marsh Posté le 16-03-2004 à 14:33:26
>Le 8, c'est une variable qui vaut 8, peu importe d'où ça vient non ?
ben si ca importe , si c est lie a la facon don tu le remplis..
>Le tab, ce que je mets dedans n'est pas important puisque le >plantage survient avant que je mette quoi que ce soit dedans : >il survient au moment de l'allocation.
bon ben si tu veux rien lacher d'aute que
mon new int[8] crache , dites moi poukoi
j ai pas envie de jouer au cmilblik moi
FK
Marsh Posté le 16-03-2004 à 14:44:51
frenchkiss a écrit : >Le 8, c'est une variable qui vaut 8, peu importe d'où ça vient non ? |
? Je ne comprends pas vraiment ta phrase mais qd je dis que ça n'importe pas, c'est que même si je remplace mon "new int[toto]" par new int[8] écrit en dur, le même problème survient. Je te rappelles aussi que le pb survient avant que je commence à remplir le tableau.
Citation : bon ben si tu veux rien lacher d'aute que |
Mais je ne demande pas de me dire exactement pourquoi (pour ça il faudrait carrément que je poste l'intégralité du code et c'est un peu trop énorme), la question du topic est simplement : quelles sont les causes connues qui peuvent faire crasher un new dans le cas général. Et quels sont les éventuels remèdes.
Marsh Posté le 16-03-2004 à 14:56:40
Toutes les cause que l'on a donné correspondent à un bug qui se déclenche avant le new. Peu importe donc comment tu fais celui-ci car le problème ne viens pas de là.
Si tu es sous Linux, essaye Valgrind. Sinon, achète Purify ou un outil equivalent
Marsh Posté le 16-03-2004 à 15:01:46
Kristoph a écrit : Toutes les cause que l'on a donné correspondent à un bug qui se déclenche avant le new. Peu importe donc comment tu fais celui-ci car le problème ne viens pas de là. |
Merci, je suis sous Windows, y a t'il des outils équivalents mais gratuits (on peut rêver on sait jamais).
Marsh Posté le 16-03-2004 à 16:24:39
tu développes avec quel environnement ? Visual ?
Marsh Posté le 16-03-2004 à 16:30:03
Combi_A_Vendre a écrit : tu développes avec quel environnement ? Visual ? |
Oui, Visual C++ 6.
EDIT : correction du quote
Marsh Posté le 16-03-2004 à 20:48:45
leFab a écrit : |
Si tu met un breakpoint a la ligne ou ca merde , la pile d'appel est elle correcte avant d'executer le new (et apres??)
A+,
Marsh Posté le 16-03-2004 à 21:25:29
gilou a écrit : |
Merci tout le monde, j'ai pu identifier le pb. Effectivement, un peu avant dans mon code, j'écris à l'extérieur du tableau.
Pour info, ça parlera sans doute à ceux qui font un peu de 3D : contrairement à ce que je pensais, le nombre de triangles de l'enveloppe convexe d'un mesh initialement concave peut être plus grand que le nombre de triangles du mesh initial.
J'avais donc initialisé mon tableau de triangles avec le nombre de triangles du mesh de base (concave). Et PAF.
Marsh Posté le 17-03-2004 à 03:34:22
Ca n'aurait peut être rien changé à ton cas, mais c'est ce genre de chose qui m'a poussé à utiliser std::vector ainsi modifié :
Code :
|
at vérifie les limites, contrairement à []
Marsh Posté le 17-03-2004 à 09:02:41
HelloWorld a écrit : Ca n'aurait peut être rien changé à ton cas, mais c'est ce genre de chose qui m'a poussé à utiliser std::vector ainsi modifié :
|
Ou alors tu utilises simplement STLPort en mode Debug car celle-ci ajoute elle même les verifications de ce genre. Et beaucoup plus de verifications de ce genre même.
Marsh Posté le 17-03-2004 à 18:52:30
kewl.
Je me suis tjrs demandé pkoi c'était pas fait (MS + SGI).
Marsh Posté le 15-03-2004 à 18:28:04
Hello,
Voilà le pb : je veux allouer un tableau de 8 int tout con.
Cette ligne toute simple plante
Dans un autre cas, le new ne plante pas, mais renvoie NULL !
Merci.
EDIT : tab -> int
Message édité par leFab le 15-03-2004 à 18:33:48