Pb lors d'une récursivité (en c)

tyb Messages postés 1 Statut Membre -  
 Bob -
Afin de débuguer un programme plus complexe, j'ai été amené à écrire et tester ce petit bout de code:

Comme vous pouvez le voir, c'est une fonction qui s'appelle indéfiniment en affichant le nombre d'itérations. Or au bout d'un programme j'ai droit à une magnifique "segmentation fault"
un petit coup de gdb me dit:
[quote]
Program received signal SIGSEGV, Segmentation fault.
0xff31f740 in _write () from /usr/lib/libc.so.1
(gdb) where
#0 0xff31f740 in _write () from /usr/lib/libc.so.1
Cannot access memory at address 0xff3efff8
(gdb) where
#0 0xff31f740 in _write () from /usr/lib/libc.so.1
#1 0xff311810 in _xflsbuf () from /usr/lib/libc.so.1
Cannot access memory at address 0xff3efffc
(gdb) where
#0 0xff31f740 in _write () from /usr/lib/libc.so.1
#1 0xff311810 in _xflsbuf () from /usr/lib/libc.so.1
Cannot access memory at address 0xff3efffc
[/quote]

Je voudrais donc avoir une confirmation comme quoi l'empilage récursif de fonction est bornée et savoir par quoi ? pointeur ? (si oui pointeur sur quoi) etc ...

[code]
#include <stdio.h>

void fonction(int i){
fprintf(stdout,"%i\n",i);
fonction(++i);
}

int main(int argc, char ** argv){
fonction(1);
}
[/code]

3 réponses

pouet
 
bonsoir,

je vois deux problemes:
1/ un int a une valeur maximale, avec ton ++ tu vas la depasser, ce qui entraine un comportement non defini.
2/ avec tes appels recursifs sans condition d'arret, tu vas exploser la pile.

tu dois tester si i > INT_MAX ou je ne sais quoi, et le cas echeant, arreter la recursion. cela dit ca doit etre du POSIX. faut te renseigner.

astuce: si je me rappelle bien, avec gdb, tu peux faire appel a la commande up, qui va remonter dans les appels de fonction, et te permettre de connaitre la valeur de i lors du segfault.

--
pouet
0
M2
 
Pour info, voila les valeurs limites de la norme ISO pour les entiers, défini dans l'en-tête <limits.h>

SHRT_MIN valeur short minimale -32767
SHRT_MAX max 32767
USHRT_MAX unsigned short max 65535
INT_MIN int min -32767
INT_MAX int max 32767
UINT_MAX unsigned int max 65535
LONG_MIN long min -2147483647
LONG_MAX long max 2147483647
ULONG_MAX unsigned long max 4294967295
0
pouet
 
>... les valeurs limites de la norme ISO pour les entiers...
merci de la precision :)

--
pouet
0
Bob
 
Y a aussi les entiers 64 bits dans la version C99 pour ceux que ça intéresse:

=> (unsigned) long long int

et les types portables:

=> int8_t/uint8_t
=> ...
=> int64_t/uint64_t
0