2016-04-14 10 views
1

Geçici olarak FIF döngüsü (işlev döngüsü) olarak adlandırdığım bir döngü fikrine geldiğimde birçok farklı ve aptal döngülerle uğraşıyordum.C - Bir işaretçiye birden fazla özyinelemeli yazıdan sonra bellek erişim hatası

Tam olarak 174665 tekrarlar yapana kadar oldukça iyi çalışıyor (normal döngüden 10 kat daha yavaş ancak nvm). 174665'in tekrarında, void fif(bool (*f)(int *x),int i,int *k){ satırında Cannot access memory at address * k işaretçisini atar. Her zaman aynı noktada çöker (aynı tekrar). Herhangi bir fikir neden? Ubuntu 15.10, gcc sürüm 5.2.1 20151010 üzerinde test. C için yeniyim, lütfen yeni hastaya sabırlı olun :). Herhangi bir yardım için şimdiden teşekkür ederiz

Kodum: Eğer call stack söndürebilir çünkü

#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

Bu, özyinelemede ilginç bir şeydir. Yığın btw'den taşıyorsun. – EOF

+0

Dürüst olmak gerekirse üniversitede öğretim görevlisi, 'IF LOOP' gibi bir şey olmadığını söyledi. Ben de benzer bir performansa sahip olup olmadığına göre bir tane yaptım (dürüst olmak gerekirse, derleyicinin onları aynı şekilde derlediğini tahmin ediyorum), ama bir adım daha ileri gitmek istediğimi düşündüm: D – Luke

+1

Muhtemelen çok derinden yinelemek ve istiflenmiş alanınızı (tüm 8 MiB) uçurdu. –

cevap

4

öyle. satırda

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

HERE işaretlenmiş, sen Recurse ve değişkenleri x, i itin ve yığın üzerine k. Yeterince zaman sonra, alan biter ve program çöküyor. -O3 ile derlerseniz, gcc bir kuyruk özyinelemeli çağrı olduğundan yinelemeye dönüştürecektir, ancak kesinlikle bu davranışa güvenmemelisiniz. Bunun yerine bir döngü ile yazmalısınız.

+3

programlama döngülerinden oldukça farklıdır Bir yığın taşması olduğunu söyleyebilirsin ... – Schwern

İlgili konular