J'ai code un programme en c++, faisant appel a diverses librairies codees en C, C++ et fortran77. La compilation se passe a merveille, et l'appliccation tourne a merveille, sauf a un endroit.
il s'agit de 6 boucles imbriquees dans le genre
for (p.p6=p.lbm;p.p6<=p.lbM;p.p6=p.p6+p.lbs)
for (p.p5=p.tbm;p.p5<=p.tbM;p.p5=p.p5+p.tbs)
for (p.p3=p.A0m;p.p3<=p.A0M;p.p3=p.p3+p.A0s)
for (p.p1=p.m0m;p.p1<=p.m0M;p.p1=p.p1+p.m0s)
for (p.p2=p.mhm;p.p2<=p.mhM;p.p2=p.p2+p.mhs)
{
subroutine_quelconque // execution du programme
}
ou tous les parametres sont stockes dans une classe appelee p. p.xxm, p.xxM et p.xxs sont respectivement la limite inferieure, superieure et l'increment pour chaque parametre (xx valant respectivement m0, A0, mh, tb et lb).
Tout marche bien jusqu'a ce que les parametres p1,p2,p3,p5,p6 prennent les valeurs suivantes
p1 = 100, p2 = 1300, p3 = 4000, p5 = 55, p6 = 0(resultat venant de gdb) .
La, paf, segfault !
Du coup je change les bornes des boucles histoire de tester uniquement le point qui foire, et la surprise ! Le programme se termine super bien ! et retourne la bonne valeur apres execution de subroutine_quelconque.
Est-ce que quelqu'un aurait une idee d'ou pourrait venir le plantage ?
D'avance merci
Benj
PS: desole, mais je n'ai pas d'accents sur mon clavier :p
# suppositions...
Posté par NeoX . Évalué à 2.
donc en gros avec les valeurs par defaut tu sature quelques part ta machine..
[^] # Re: suppositions...
Posté par NeoX . Évalué à 1.
p1 = 100, p2 = 1300, p3 = 4000, p5 = 55, p6=0
soit le 55x4000x100x1300 = 28.600.000.000e element
si tu fais des pas de 1 dans tes boucles
[^] # Re: suppositions...
Posté par benjf . Évalué à 1.
# Débordement de tableau ?
Posté par alf . Évalué à 6.
Un tel plantage (segmentation fault lors de la manipulation de pointeurs pointant dans des tableaux) est souvent dû à un débordement des tableaux en question. D'où la question : ces valeurs sont-elles dans les bornes de tes tableaux (ou des espaces mémoire alloués dynamiquement) ?
En passant, en C, pour un tableau de taille N (i.e. dont les indices valides vont de 0 à N-1 inclus), le fait même de calculer l'adresse du pseudo-élément d'indice supérieur à N cause un comportement indéfini (*). Si la même chose est valable en C++ (je n'en sais rien), alors il est possible que tes incrémentations pi += pasi débordent les tableaux, et que cela suffise à causer un plantage.
Plus concrètement : si on suppose
int array[10];
p.mhm=&array[0];
p.mhM = 10;
p.mhs = 3;
Alors, lors de la boucle for (p.p2=p.mhm;p.p2<=p.mhM;p.p2=p.p2+p.mhs) { /* ... */ }, p.p2 prendra les valeurs &array[0], &array[3], &array[6], &array[9] sans problème. Puis, à la fin de la 4e itération, l'incrément affectera la valeur "&array[12]", qui est invalide. En C, le comportement indéfini surviendrait ici, et se manifesterait probablement par un segmentation fault sur ton système.
A toi de voir si ton code permet d'être dans une telle situation, et si le comportement indéfini s'applique aussi en C++.
(*) Le calcul de l'adresse du pseudo-élément d'indice N est par contre bien défini, c'est une exception tolérée pour faciliter les traitements de tableaux par pointeurs. Par contre, essayer d'accéder (en lecture ou en écriture) au contenu de ce pseudo-élément (qui n'existe pas) cause un comportement indéfini. Tout ceci est valable en C, je le rappelle ; je ne sais pas si ça concerne aussi le C++.
[^] # Re: Débordement de tableau ?
Posté par NeoX . Évalué à 2.
bravo...
[^] # Re: Débordement de tableau ?
Posté par benjf . Évalué à 1.
En jouant avec gdb, j'ai finalement identifie d'ou venait le probleme... d'une des libraries fortran (donc je ne suis peut-etre plus dan le bon forum ... je vais neanmoins exposer le probleme):
xx0 = dmin1(mn(1),mn(2),mn(3),mn(4))
xx1 = dmax1(mn(1),mn(2),mn(3),mn(4))
idummy = 1
do i = 1,4
if(mn(i).eq.xx0)then
iord(1) = i
elseif(mn(i).eq.xx1)then
iord(4) = i
else
irem(idummy) = i
idummy = idummy+1
endif
enddo
if(mn(irem(1)).le.mn(irem(2)))then
[...]
et irem(2) vaut 1060472881 (et mn va de 1 a 4...), d'ou le segmentation fault.
par contre je ne comprends pas du tout comment irem(2) peut prendre cette valeur. Dams mon cas mn(1)=xx0 et mn(4)=xx1, donc je devrais avoir iord(1)=1, iord(4)=4,irem(1)=2 et irem(2)=3. Ce qui est le cas, sauf pour irem(2) !
[^] # Re: Débordement de tableau ?
Posté par daggett . Évalué à 3.
Mais que se passe-t-il si tous les mn() sont égaux, ou qu'au moins 2 valeurs soient égales au min ou au max ? Dans ce cas seuls le 1er ou les 2 premiers "if" seront valides, et le else final ne sera jamais pris, ou pris 1 seul fois. irem(2), voire irem(1) ne sera jamais affecté et restera égal à la valeur de la case mémoire où il se trouve, donc aléatoire.
Vérifie que ce cas particulier est bien traité dans ton code. Par exemple, change ta routine fortran pour tester si idummy vaut bien 3 à la fin, et sinon quitte en affichant toutes tes valeurs mn(); tu devrais voir la cause du problème.
[^] # Re: Débordement de tableau ?
Posté par benjf . Évalué à 4.
Un grand merci a tous !
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.