2016-04-14 7 views
1

Je jouais avec de nombreuses formes de boucles différentes et stupides quand je suis arrivé à une idée de boucle que j'ai appelée temporairement FIF loop (boucle de fonction).C - Erreur d'accès mémoire après plusieurs écritures récursives sur un seul pointeur

Cela fonctionne plutôt bien (c'est 10 fois plus lent que la boucle normale mais nvm que pour l'instant) jusqu'à ce qu'il fasse exactement 174665 répétitions. Sur 174665th répétition il jette Cannot access memory at address sur * k pointeur dans la ligne: void fif(bool (*f)(int *x),int i,int *k){. Il se bloque toujours dans le même point (même répétition). Des idées pourquoi? Test sur Ubuntu 15.10, gcc version 5.2.1 20151010. Je suis nouveau à C alors s'il vous plaît, soyez patient à newbi :). Merci d'avance pour toute aide

Mon code:

#include <stdio.h> 
#include <stdbool.h> 

#define REPEATS 1.8E5 

#ifdef WIN32 

#include <windows.h> 
double get_time() 
{ 
    LARGE_INTEGER t, f; 
    QueryPerformanceCounter(&t); 
    QueryPerformanceFrequency(&f); 
    return (double)t.QuadPart/(double)f.QuadPart; 
} 

#else 

#include <sys/time.h> 
#include <sys/resource.h> 

double get_time() 
{ 
    struct timeval t; 
    struct timezone tzp; 
    gettimeofday(&t, &tzp); 
    return t.tv_sec + t.tv_usec*1e-6; 
} 

#endif 

bool fifFunction(int *k); 
void fif(bool (*f)(int *x),int i,int *k); 

int main() 
{ 
     //FIF 

     printf("FIF loop\n"); 
     double t = get_time(); 
     int k = 0; 
     fif(fifFunction,REPEATS,&k); 
     printf("time: %f\n",get_time() - t);  
    return 0; 
} 

bool fifFunction(int *k) 
{ 
     return (*k = *k + 1); 
} 


void fif(bool (*f)(int *x),int i,int *k){ 
    if (i > 0){ 
     if ((*f)((k)) == false){ 
      return; 
     } 
     fif(f,(i-1),k); 
    } 
} 
+4

Eh bien, c'est une interprétation intéressante de la récursivité. Vous débordez votre pile btw. – EOF

+0

Pour être honnête, l'un des conférenciers de l'université a dit qu'il n'y a rien de tel que 'IF LOOP'. J'en ai fait un en utilisant si et goto qui a des performances similaires à (pour être honnête, je suppose que compiller les compile de la même manière), mais je pensais que je voudrais aller un peu plus loin: D – Luke

+1

Vous êtes probablement récursif trop profondément et ont soufflé votre espace de pile (tous les 8 MiB de celui-ci). –

Répondre

4

C'est parce que vous soufflez le call stack.

void fif(bool (*f)(int *x),int i,int *k){ 
    if (i > 0){ 
     if ((*f)((k)) == false){ 
      return; 
     } 
     fif(f,(i-1),k); // HERE 
    } 
} 

Sur la ligne marquée HERE, vous RECURSE, et pousser les variables x, i et k sur la pile. Après assez de temps, vous manquez d'espace et le programme se bloque. Si vous compilez avec -O3, gcc le convertira en itération puisqu'il s'agit d'un appel récursif en queue, mais vous ne devez absolument pas vous fier à ce comportement. Vous devriez plutôt écrire ceci avec une boucle.

+3

Vous pourriez dire qu'il y avait un débordement de pile ... – Schwern