Débordement de tableau invisible !!! - C++ - Programmation
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 ).
Marsh Posté le 14-11-2006 à 15:56:08
Et ça n'inquiète personne ???
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...
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.
Marsh Posté le 14-11-2006 à 16:04:13
Taz a écrit : utilise std::vector. |
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 ?
Marsh Posté le 14-11-2006 à 16:20:41
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 !
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 ?
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
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.
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
Marsh Posté le 14-11-2006 à 18:27:17
red faction a écrit : c++ nymp |
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...
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 !
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.
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"...
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
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à.
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.
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.
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.
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.
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
Marsh Posté le 15-11-2006 à 15:56:46
SkippyleGrandGourou a écrit : 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... |
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++.
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... 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...
Marsh Posté le 16-11-2006 à 12:06:07
ReplyMarsh Posté le 16-11-2006 à 12:21:56
ReplyMarsh 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... |
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 )
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.
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 ?
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
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é. |
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.
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.
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.
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...
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...
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.
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
Marsh Posté le 17-11-2006 à 09:59:19
Taz a écrit : attitude stupide et malappris |
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 |
Marsh Posté le 18-11-2006 à 19:59:39
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
Marsh Posté le 18-11-2006 à 23:52:19
bjone a écrit : |
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: |
Clair que là, c'est un peu la base...
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... |
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.
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 ). Le programme suivant :
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...) :
Implique que :
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... 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