Pb lors d'une récursivité (en c)
tyb
Messages postés
1
Statut
Membre
-
Bob -
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]
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
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
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
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
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