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

  1. 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
  2. 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
    1. pouet
       
      >... les valeurs limites de la norme ISO pour les entiers...
      merci de la precision :)

      --
      pouet
      0
  3. 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