2011-05-29 19 views
5

Ben imzası ile bir işlevi vardır:Bu değişken neden dönüş ifadesinden sonra değişir?

Bu son iki satırı vardır
int exe(int stack[][STACKSIZE], int sp[], int reg[][REGISTERSIZE], int next_instruct[], 
     int next_inst[], int cur_proc, int *terminate); 

:

printf("TWO cur_proc: %d\n",cur_proc); 
return NORMAL; 

Ve böyle denir:

printf("ONE cur_proc: %d\n",cur_proc); 
msg = exe(stack,sp,reg, next_instruct, next_instruct, cur_proc, &terminate); 
printf("THREE cur_proc: %d\n",cur_proc); 

Ve geçen am exe()'un içinde "salt okunur" (değerden geçirilmesi önemli değil) değişken olarak kabul edilen cur_proc. Eşyalarımı exe() içinde yap.

Ve çıkış: Ben bu mümkün olumsuz biriyle yazılır ki herhangi bir neden göremiyorum olarak

ONE cur_proc: 1 
TWO cur_proc: 1 
THREE cur_proc: -1 

Bu benim için çok kafa karıştırıcı.

Bu garip davranış için olası bir sebep nedir?

+0

Cur_proc değerinin ne zaman değiştiğini görmenin basit bir yolu argüman bildirimini const ile öneklemektir. Derleyici, değerini değiştirdiğiniz yerdeki bir hatayı atar. –

+0

Önce bunu denedim. Herhangi bir hata yoktu çünkü derleyici, değişmediğini anladığı için. –

+0

Ardından programınızı [valgrind] ile çalıştırın (http://valgrind.org). Programınızın bir başka kısmı muhtemelen yığınınızı bozuyor. –

cevap

4

Muhtemelen dizilerden birinin sınırlarının dışında yazıyorsunuzdur.

İşlevde, değişkenin kopyasına, orijinal değişkende değil, çağıran işleve bakarsınız. Bu nedenle, işlev içinde printf(), arama işlevinde değerin bozulup bozulmadığını size bildirmez.

Geçirilen dizilere bakın ve bu işlevin içinde değiştirilen, en olası suçludur - veya değiştirilmiş olanlardır. Dizilerden hiçbiri yapılı kalifiye olmadığından, hangisinin değiştirildiğini söylemek zordur, ancak bir şey büyük olasılıkla sınırların dışına çıkmaktadır.

Çağrma işlevinde arama işlevinin içinde cur_proc değişikliğinin ne zaman gerçekleştiğini izlemek istiyorsanız, işaretçi cur_proc işlevine - yanı sıra değer yerine - geçirin ve değeri işaretçi aracılığıyla yazdırın .

+0

İşte bu. Yığın işlevleri sınırlarının dışında yazıyor. Cur_proc işaretçisine bakarak onu temizledim. –

3

exe işlevinin içindeki kod, iletilen dizilerden birinde geçersiz bir konuma veri yazıyorsa, yığın yığınının üstündeki yerel değişkenlerin değerini potansiyel olarak değiştirecek şekilde bozulabilir (diğer kötü şeyler arasında)). fonksiyonlar bakış açısıyla değişkenin salt okunur doğası göz önüne alındığında

, ya bu oluyor ya da başka iş parçacığı cur_proc değerini değiştiriyorsa - Eğer diş ile işe yaramaz değilseniz eski daha muhtemel görünüyor.

Çoğu hata ayıklayıcı, "bellekte belirli bir adreste değerin değiştirilmesi" konusunda bir kesme noktası yerleştirmenize izin verir. Eğer cur_proc adresini alırsanız ve bu adresteki değer değiştiğinde kırılırsanız suçunuzu bulmanız gerekir.

+0

Bu benim de ilk düşüncemdi, ama daha önce hiç görmedim. Bunu nasıl ayıklardım?(Bu iş parçacığı BTW'siz) –

+0

Çoğu hata ayıklayıcı, "belleğin belirli bir adresindeki değerin değiştirilmesi" konusunda bir kesme noktası koymanıza izin verir. Eğer cur_proc adresini alırsanız ve bu adresteki değer değiştiğinde kırılırsanız suçunuzu bulmanız gerekir. –

+0

... demişti ki, hata ayıklayıcının etrafında yolunuzu bilmiyorsanız, daha düşük teknoloji ve daha basit bir yol cevabını Jonathan Leffler tarafından açıklanmıştır - iyi düşünmeye değer. –

İlgili konular