Débordement de tableau invisible !!!

Débordement de tableau invisible !!! - C++ - Programmation

Marsh Posté le 14-11-2006 à 15:20:17    

Salut,
 
Je me suis rendu compte d'un truc qui me semble extrêmement dangereux (et surtout à cause duquel il m'a fallu des plombes pour débuguer mon programme :fou: ). Le programme suivant :

Code :
  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int tableau[2];
  6. tableau[30]=5;
  7. cout<<"Je vaux "<<tableau[30]<<endl;
  8. return 1;
  9. }

donne (tenez-vous bien) : "Je vaux 5" !!!
 
Et le pire, quand dans une classe sont déclarés deux tableaux à la suite (c'était mon problème, comment j'ai galéré pour trouver ça...) :

Code :
  1. int trux[10];
  2. int bidule[10];


Implique que :

Code :
  1. bidule[0]=5;
  2. trux[10]=30; // Une petit erreur de rien du tout dans l'initialisation
  3. cout<<"bidule[0] vaut "<<bidule[0]<<endl;


affiche : "bidule[0] vaut 30" !!!
 
Je pense que ça méritait d'être signalé... Est-ce un bug ? Est-il corrigé ?
 
EDIT : Ça me pose d'ailleurs un petit problème, j'aimerais justement mettre un try-catch sur un truc comme ça : j'ai une classe avec une fonction qui prend en arguments un tableau et le nombre de cases de ce tableau, et je voudrais capturer l'exception en cas d'overflow, si le nombre de case est plus grand que la taille réelle du tableau. Mais là ça peut pas marcher...  :heink: Est-ce que ça peut venir de mes options de compilation ?
 
PS : g++ -v => gcc version 4.0.2 20051125 (Red Hat 4.0.2-8)


Message édité par SkippyleGrandGourou le 14-11-2006 à 15:34:30
Reply

Marsh Posté le 14-11-2006 à 15:20:17   

Reply

Marsh Posté le 14-11-2006 à 15:40:42    

Salut,
 
C'est un comportement... disons, normal dans l'anormal. Les tableaux se suivent, donc le débordement fait que tu écris dans le 2nd.
Ca peut très mal se passer: imagine qu'avec des tableaux dynamiques, tu peux corrompre autre chose que ta propre appli. Dans le cas de variables locales, tu ne fais que toucher à tes variables, ton prog buggera mais sans plus (enfin, à toi de gérer quoi :) ).

Reply

Marsh Posté le 14-11-2006 à 15:44:09    

Ce sont des problèmes "biens connus" en C.

Reply

Marsh Posté le 14-11-2006 à 15:56:08    

Et ça n'inquiète personne ???  :ouch:  
 
Pourtant il me semble bien avoir connu (intimement même... ;) ) des segmentation faults et des "array index out of range", mais depuis que j'ai découvert ça j'arrive plus à en avoir...  :cry:

Reply

Marsh Posté le 14-11-2006 à 15:56:12    

utilise std::vector.
v.at(i) lèvera une exception si i n'est pas un index valide.

Reply

Marsh Posté le 14-11-2006 à 16:04:13    

Taz a écrit :

utilise std::vector.
v.at(i) lèvera une exception si i n'est pas un index valide.

Oui, je pense que c'est ce que je vais faire, mais je voudrais que l'utilisateur puisse passer en argument un simple tableau. Il y a moyen de convertir un tableau en vector sans connaître la taille du tableau, ou je demande (encore !) l'impossible ?

Reply

Marsh Posté le 14-11-2006 à 16:14:38    

Tu demandes l'impossible.

Reply

Marsh Posté le 14-11-2006 à 16:20:41    

:cry:  :cry:  :cry:  
Je m'en doutais un peu... Bon, tant pis pour l'utilisateur (ou pour la sécurité, selon les fruits de ma réflexion à venir...).
 
Merci ! :jap:

Reply

Marsh Posté le 14-11-2006 à 16:42:59    

Si c'est pour le pilotage d'un avion, y'a peut-être pas trop de choix ?

Reply

Marsh Posté le 14-11-2006 à 17:44:54    

c nymp
vous vous plaignez du C parce qu'il ne teste pas si les index ne depassent pas du tableau, et un tas dautre trucs quil pourrait tester au runtime
 mais c justement la toute la force du C : la vitesse
 
ceux que ca ninteresse pas passez votre chemin et ruez vous sur python, .Net , Java et autres usines a gaz

Message cité 2 fois
Message édité par red faction le 14-11-2006 à 17:45:44
Reply

Marsh Posté le 14-11-2006 à 17:44:54   

Reply

Marsh Posté le 14-11-2006 à 17:51:40    

red faction a écrit :

mais c justement la toute la force du C : la vitesse


k lol.
 

Citation :

ceux que ca ninteresse pas passez votre chemin et ruez vous sur python, .Net , Java et autres usines a gaz


olololol.

Reply

Marsh Posté le 14-11-2006 à 17:56:26    

SkippyleGrandGourou a écrit :

Oui, je pense que c'est ce que je vais faire, mais je voudrais que l'utilisateur puisse passer en argument un simple tableau. Il y a moyen de convertir un tableau en vector sans connaître la taille du tableau, ou je demande (encore !) l'impossible ?

il suffit de ne pas utiliser de tableau

Reply

Marsh Posté le 14-11-2006 à 18:27:17    

red faction a écrit :

c++ nymp
vous vous plaignez du C++ parce qu'il ne teste pas si les index ne depassent pas du tableau, et un tas dautre trucs quil pourrait tester au runtime
 mais c++ justement la toute la force du C++ : la vitesse

:lol:  :lol:  :lol: C'est sûr que chercher une aiguille dans une botte de foin (en l'occurence un tableau mal initialisé perdu au milieu de milliers de lignes de code et qui contamine un tableau bien initialisé, lui...), ça aide à gagner en vitesse...  :sarcastic:  

red faction a écrit :

Mieux vaut rouler à 180Km/h avec un pneu crevé que rouler à 170KM/h seulement !

;)
 

red faction a écrit :

ceux que ca ninteresse pas passez votre chemin et ruez vous sur python, .Net , Java et autres usines a gaz

Non, pas le choix...
 

Taz a écrit :

il suffit de ne pas utiliser de tableau

Non, pas le choix... Enfin si : le vecteur. Ce qui sera d'ailleurs l'occasion pour nous deux (moi + l'utilisateur en question) de faire un premier pas vers la STL !  :bounce:

Message cité 1 fois
Message édité par SkippyleGrandGourou le 14-11-2006 à 18:27:59
Reply

Marsh Posté le 14-11-2006 à 18:38:00    

je comprends que tu ne comprends rien. Y a pas à avoir de premier pas vers STL. Quand t'apprends le C, tu fais du printf direct. Ben quand t'apprends le C++, tu fais du vector, string, etc direct.

Reply

Marsh Posté le 14-11-2006 à 19:01:19    

Alors faudra que tu m'explique pourquoi la STL est toujours reléguée aux derniers chapitres des cours et Faq C++, avec des avertissements style "il faut impérativement avoir compris en profondeur les fonctionnalités les plus avancées du C++ pour appréhender correctement la bibliothèque standard"... ;)

Reply

Marsh Posté le 14-11-2006 à 19:14:13    

Parce que pour bien la comprendre, c'est vital de comprendre les concepts utilisés? Sinon, tu les comprends pas.
Mais le dernier chapitre ne signifie pas le moins important...
 
PS: et j'ai jamais eu de tels warning dans mes bouquins ;)

Reply

Marsh Posté le 14-11-2006 à 19:24:01    

IrmatDen a écrit :

Mais le dernier chapitre ne signifie pas le moins important...

Certes, je n'ai pas dit ça, mais tu commence rarement par le dernier chapitre... ;)
 

IrmatDen a écrit :

PS: et j'ai jamais eu de tels warning dans mes bouquins ;)

Celui-ci vient de là.
 

Reply

Marsh Posté le 14-11-2006 à 19:56:22    

SkippyleGrandGourou a écrit :

Alors faudra que tu m'explique pourquoi la STL est toujours reléguée aux derniers chapitres des cours et Faq C++, avec des avertissements style "il faut impérativement avoir compris en profondeur les fonctionnalités les plus avancées du C++ pour appréhender correctement la bibliothèque standard"... ;)


_Accelerated C++_  présente std::string avant de savoir ce qu'est une classe.  

Reply

Marsh Posté le 15-11-2006 à 09:16:09    

SkippyleGrandGourou a écrit :

Alors faudra que tu m'explique pourquoi la STL est toujours reléguée aux derniers chapitres des cours et Faq C++, avec des avertissements style "il faut impérativement avoir compris en profondeur les fonctionnalités les plus avancées du C++ pour appréhender correctement la bibliothèque standard"... ;)


parce que ce sont de mauvais enseignements.

Reply

Marsh Posté le 15-11-2006 à 14:26:11    

sinon pour le comportement que décrit SkippyleGr andGourou ça m'est déja arrivé, un autre exemple si tu alloues dynamiquement un tableau, tu l'utilises et tout, puis tu fais un free(tab), puis apres tu fais par ex tab[5] tu retrouves la valeur!! en fait il me semble que ça dépend des options de compilation, et gcc est assez "cool" si on lui rentre rien dedans. Je pense que si tu fais le free, la mémoire est effectivment libérée, mais les valeurs restent en mémoire (pas de remise à zeros) et le pointeur est juste un curseur que tu balades dans cette mémoire, si tu fais pas tab=NULL; apres le free ben tu peux encore te balader aux adresses de ta mémoire via tab.


Message édité par neg'gwada le 15-11-2006 à 14:30:40

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 15-11-2006 à 14:36:42    

Il faut avoir gardé un pointeur sur la zone, parce qu'il me semble que free() remet la valeur du pointeur à 0.

Reply

Marsh Posté le 15-11-2006 à 15:03:57    

non, enfin pas de base sous gcc (mingw en tout cas), après ça dépend p'tetre du compilo


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 15-11-2006 à 15:56:46    

SkippyleGrandGourou a écrit :

:lol:  :lol:  :lol: C'est sûr que chercher une aiguille dans une botte de foin (en l'occurence un tableau mal initialisé perdu au milieu de milliers de lignes de code et qui contamine un tableau bien initialisé, lui...), ça aide à gagner en vitesse...  :sarcastic:  


 
la remarque n'est pas là, sa remarque est que le coût de vérification à chaque accès d'un tableau peut dramatiquement réduire les performances, d'autant plus que la cause est souvent liée à un algorithme ou une implémentation d'algorithme erronée, ou un dépassement dans un quelquonque calcul qui influence l'indexation.
 
moi ce qui m'aflliges c'est qu'un mec qui demande un truc débile à son compilo, se plaint que le compilo fasse son truc débile, d'une part, et qu'apparemment, on lui a jamais expliqué comment fonctionnait le C ou le C++.
 

Reply

Marsh Posté le 16-11-2006 à 11:52:35    

bjone a écrit :

la remarque n'est pas là, sa remarque est que le coût de vérification à chaque accès d'un tableau peut dramatiquement réduire les performances,

J'avais compris, merci...  :sarcastic: Ce que je voulais dire, c'est que si tu perds plus de temps à cause de ça pendant la phase de programmation que tu n'en gagneras pendant toute l'exécution, ça sert à rien...
 

bjone a écrit :

moi ce qui m'aflliges c'est qu'un mec qui demande un truc débile à son compilo, se plaint que le compilo fasse son truc débile, d'une part, et qu'apparemment, on lui a jamais expliqué comment fonctionnait le C ou le C++.

Et moi ce qui m'afflige ce sont tous ces gens imbus d'eux-mêmes qui semblent penser qu'il faut au minimum un niveau doctorat en programmation pour avoir le droit de prétendre programmer et de poser des questions, et qui se permettent de faire des commentaires désobligeants sur des personnes qu'ils ne connaissent pas. D'autant plus que dans le cas présent, le truc débile est une faute de frappe, ce qui peut arriver à tout le monde, même à un bjone, un Taz ou un Bjarne Stroustrup, qui peut avoir des conséquences dangereuses (si ça se trouve c'est à cause d'un débordement de tableau de ce genre que la navette Challenger s'est scratchée, qui sait...) et qui à mon humble avis ne devrait pas passer la compilation. Mais bon, ce que j'en dis...  :sarcastic:

Reply

Marsh Posté le 16-11-2006 à 12:06:07    

commence par compiler en -Wall, on verra après

Reply

Marsh Posté le 16-11-2006 à 12:21:56    

Taz a écrit :

commence par compiler en -Wall, on verra après

C'est déjà le cas.
 

Reply

Marsh Posté le 16-11-2006 à 12:57:54    

Citation :

Et moi ce qui m'afflige ce sont tous ces gens imbus d'eux-mêmes qui semblent penser qu'il faut au minimum un niveau doctorat en programmation pour avoir le droit de prétendre programmer et de poser des questions, et qui se permettent de faire des commentaires désobligeants sur des personnes qu'ils ne connaissent pas. D'autant plus que dans le cas présent, le truc débile est une faute de frappe, ce qui peut arriver à tout le monde, même à un bjone, un Taz ou un Bjarne Stroustrup, qui peut avoir des conséquences dangereuses (si ça se trouve c'est à cause d'un débordement de tableau de ce genre que la navette Challenger s'est scratchée, qui sait...) et qui à mon humble avis ne devrait pas passer la compilation. Mais bon, ce que j'en dis...  :sarcastic:


 
T'inquiètes ça m'est arrivé. C'est l'avantage & l'inconvéniant du C & C++: tu peux faire ce que tu veux comme avec un couteau: tu peux tailler des figurines ou tu peux te le mettre dans la main. (ou automatiser la découpe de la figurine adaptée au dimensions du matériau que tu vas tailler :D)
 
Ce qui est important c'est d'apprendre des pratiques correctes.
Par exemple ton débordement est à tous le coups dû au fait que tu as utilisé quelque chose de limité.
genre "5 bidules ça suffit, etc..." et plus loin tu fais ta boucle en y mettant 5 dans ta boucle, truc généralement merdique à maintenir.
généralement le code qui a plein de bornes en dur et trop de choses statiques sont des nis à débordements.

Message cité 2 fois
Message édité par bjone le 16-11-2006 à 14:39:50
Reply

Marsh Posté le 16-11-2006 à 12:59:17    

mais je veux dire:
 
int tableau[2];
tableau[30]=5;
 
aucun prof ne t'a jamais expliqué que c'était une erreur possible & légale de base ?

Reply

Marsh Posté le 16-11-2006 à 14:09:38    

moi j'ai juste eu vite fait quelques cours de prog en ecole d'ingé, et jamais on m'a parlé de possibilité de débordement de mémoire :/


Message édité par neg'gwada le 16-11-2006 à 14:09:54

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 16-11-2006 à 14:26:01    

bjone a écrit :

Par exemple ton débordement est à tous le coups dû au fait que tu as utilisé quelque de limité.
genre "5 bidules ça suffit, etc..." et plus loin tu fais ta boucle en y mettant 5 dans ta boucle, truc généralement merdique à maintenir.

Tutafé. Justement parce que la plupart de mes tableaux sont des tableaux de pointeurs sur des objets plus complexes, et que comme ça dès qu'il y a débordement ça me fait une segfault, je trouve rapidement d'où ça vient et je fais en sorte que ça puisse plus arriver. Donc la leçon à retenir serait de systématiquement surévaluer la taille des tableaux de valeurs ? (ce qui ne résoud pas le problème en cas d'accès à une case vide, mais évite la contamination, ce qui divise déjà notablement les riques, effectivement)
 

bjone a écrit :

aucun prof ne t'a jamais expliqué que c'était une erreur possible & légale de base ?

Bof, comme neg'gwada, les cours de programmation que j'ai eu à la fac étaient surtout des cours d'introduction, le genre de truc où tu dois faire un programme qui affiche trois pauvres étoiles au bout de la 3e séance de TP (à part un cours de programmation logique en première année de deug)... Donc je les ai systématiquement séchés.  :ange:

Message cité 2 fois
Message édité par SkippyleGrandGourou le 16-11-2006 à 14:29:39
Reply

Marsh Posté le 16-11-2006 à 14:30:13    

SkippyleGrandGourou a écrit :

Donc la leçon à retenir serait de systématiquement surévaluer la taille des tableaux de valeurs ?  


 
Non la leçon à retenir c'est de tout penser en dynamique (stl/vector par exemple), et de bien structurer pour ne pas indicer dans le vide.

Reply

Marsh Posté le 16-11-2006 à 14:31:29    

SkippyleGrandGourou a écrit :

Tutafé. Justement parce que la plupart de mes tableaux sont des tableaux de pointeurs sur des objets plus complexes, et que comme ça dès qu'il y a débordement je trouve rapidement d'où ça vient et je fais en sorte que ça puisse plus arriver. Donc la leçon à retenir serait de systématiquement surévaluer la taille des tableaux de valeurs ?


 
Non, la leçon à retenir est d'être capable de maîtriser la taille de ses tableaux, en sachant à tout moment combien d'éléments ils sont supposés contenir.

Reply

Marsh Posté le 16-11-2006 à 14:43:42    

bjone a écrit :

Non la leçon à retenir c'est de tout penser en dynamique (stl/vector par exemple), et de bien structurer pour ne pas indicer dans le vide.

Oui, faut vraiment que je m'y mettes, bien que dans ce cas particulier ça me gêne un peu, le principal utilisateur auquel le programme est destiné étant un ancien fortraniste et pawiste qui truffe ses programmes "c++" de printf...  :whistle:  
 

Chaos Intestinal a écrit :

Non, la leçon à retenir est d'être capable de maîtriser la taille de ses tableaux, en sachant à tout moment combien d'éléments ils sont supposés contenir.

Aussi, mais c'est pas toujours évident...  :ange:  

Reply

Marsh Posté le 16-11-2006 à 15:02:28    

en principe ça devrait être naturel :/
 
alors après ça dépends de plein de choses.
 

Reply

Marsh Posté le 16-11-2006 à 22:46:52    

perso, jamais eu besoin de stl(vector) jusqu'à présent, sauf une fois mais bon après il ya peu etre une habitude à prendre


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 17-11-2006 à 08:39:21    

attitude stupide et malappris

Reply

Marsh Posté le 17-11-2006 à 09:59:19    

Taz a écrit :

attitude stupide et malappris

:o  

neg'gwada a écrit :

perso, jamais eu besoin de stl(vector) jusqu'à présent, sauf une fois mais bon après il ya peu etre une habitude à prendre


 


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 18-11-2006 à 19:59:39    

[:doc skeyou]  tin v'la que comme par hazard pour la premiere fois, je me retrouve avec un débordement de mémoire dans mon code en Fortran, 3 jours pour trouver le bleme


Message édité par neg'gwada le 18-11-2006 à 20:00:05

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 18-11-2006 à 23:52:19    

bjone a écrit :


Par exemple ton débordement est à tous le coups dû au fait que tu as utilisé quelque chose de limité.
genre "5 bidules ça suffit, etc..." et plus loin tu fais ta boucle en y mettant 5 dans ta boucle, truc généralement merdique à maintenir.
généralement le code qui a plein de bornes en dur et trop de choses statiques sont des nis à débordements.


En temps réel dur embarqué, il arrive que l'on impose de ne faire que de l'allocation statique une bonne fois pour toutes au démarrage.

bjone a écrit :

mais je veux dire:
 
int tableau[2];
tableau[30]=5;
 
aucun prof ne t'a jamais expliqué que c'était une erreur possible & légale de base ?


Clair que là, c'est un peu la base...


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 18-11-2006 à 23:57:17    

SkippyleGrandGourou a écrit :

Oui, faut vraiment que je m'y mettes, bien que dans ce cas particulier ça me gêne un peu, le principal utilisateur auquel le programme est destiné étant un ancien fortraniste et pawiste qui truffe ses programmes "c++" de printf...  :whistle:  
:


Le F77 ne connait que l'alloc de tableaux statiques. De plus, les indices commencent à 1, d'où ton erreur classique, et enfin, tu vas galérer avec les tableaux à N dimensioins (N>1), vu que les indices sont inversés / C.
Enfin, d'une façon générale, et sauf cas très exceptionnel, les fortranistes ne savent pas programmer.

Message cité 1 fois
Message édité par el muchacho le 18-11-2006 à 23:58:03

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed