2011-05-29 126 views
5

我有簽名的函數:爲什麼在返回語句後這個變量會改變?

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; 

,被稱爲是這樣的:

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); 

而且我傳遞cur_proc這被認爲是exe()內的「只讀」(不是值得傳遞的值)變量。做我的東西在exe()裏面。

而且我的輸出是:

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

,因爲我看不到任何理由,這可能可能的負一層覆蓋,這是非常令人困惑我。

這種奇怪行爲的可能原因是什麼?

+0

查看cur_proc更改其值的簡單方法是將參數聲明加上const前綴。編譯器會在您更改其值的確切位置發出錯誤。 – 2011-05-29 06:24:09

+0

我先試了一下。沒有錯誤,因爲只要編譯器知道它沒有改變。 – 2011-05-29 06:40:06

+0

然後用[valgrind](http://valgrind.org)運行你的程序。你的程序的另一部分可能會破壞你的堆。 – 2011-05-29 07:06:29

回答

4

您可能正在寫入其中一個數組的邊界之外。

函數內部,您正在調用函數中查找變量的副本,而不是原始變量。因此,函數內部的printf()不會告訴您有關值在調用函數中何時損壞的信息。

查看傳遞的數組,並且在函數內部修改的數組是最可能的罪魁禍首 - 或者被修改的數組。由於沒有一個數組是const限定的,所以很難說哪一個被修改,但有些可能會超出界限。

如果您想在調用函數的變化cur_proc從被調用函數內發生的跟蹤,將指針傳遞給cur_proc到功能 - 以及或作爲替代的價值 - 通過指針打印值。

+0

就是這樣。堆棧函數正在寫入範圍之外。看着cur_proc的指針清除了它。 – 2011-05-29 06:37:33

3

如果exe函數中的代碼將數據寫入其中一個傳入數組的某個無效位置,堆棧可能會損壞,這可能會改變堆棧中較高位置的局部變量的值(以及其他不好的事情)。

從函數的角度給出變量的只讀本質,無論是發生這種情況還是另一個線程正在修改cur_proc的值 - 如果您沒有線程調整,前者似乎更有可能。

大多數調試器允許您在「更改內存中特定地址的值」時放置斷點。如果你得到了cur_proc的地址,並在這個地址的值發生變化時斷開,你應該找到你的罪魁禍首。

+0

這也是我的第一個想法,但我以前從未見過。我將如何調試?(這是非線程BTW) – 2011-05-29 06:16:43

+0

大多數調試器允許您在「在內存中的特定地址更改值」放置斷點。如果你得到了cur_proc的地址,並在這個地址的值發生變化時斷開,你應該找到你的罪魁禍首。 – 2011-05-29 06:18:39

+0

......話說回來,Jonathan Leffler在他的回覆中描述瞭如果你不瞭解調試器的方式,那麼技術含量較低且更簡單的方法 - 值得考慮。 – 2011-05-29 06:24:06

相關問題