2011-06-28 68 views
2
int (^b[3])(); 
for (int i=0; i<3; i++) 
    b[i] = ^{ return i;}; 
for (int i=0; i<3; i++) 
    printf("b %d\n", b[i]()); 

在第一個循環中創建塊結構,然後將此結構的地址賦給b [i]元素,然後塊結構被銷燬。問題是爲什麼第二個循環中的b [i]包含有效/相同的指向塊最後狀態的指針?我期望第二個循環崩潰,因爲元素指向無效的堆棧區域。堆棧塊壽命

我知道這不是最好的一段代碼,我沒有使用它。但想要理解爲什麼在第一次循環之後,當塊結構應該被銷燬時,我有有效的堆棧對象。

+0

相關:[無法理解塊的詞法作用域](http://stackoverflow.com/questions/6647918/unable-to-understand-the-blocks-lexical-scope/6648368#6648368) – 2011-09-13 13:05:55

回答

2

由於您在創建範圍之外使用了某個塊,因此您的代碼會顯示未定義的行爲。而應該這樣寫:

b[i] = [^{ return i; } copy]; 

變量不會導致問題,因爲它實際上是複製到塊的用const修飾符範圍增加。你可以通過聲明變量__block限定符來賦予變量的塊寫入訪問權限,當修改一個引用塊時,它具有將變量移動到堆棧的奇怪副作用(即,更改其地址) 。

+1

我知道塊如果我不復制到堆中,它們將在堆棧中啓動並限制在範圍內。但爲什麼指針仍然有效? – Pablo

+0

除了塊本身之外,沒有涉及指針。該變量被複制到塊的作用域中。既然你沒有創建塊的副本,'i'的副本仍然保留在堆棧上,並且在第二個循環中使用它的純運氣,當它超出範圍時仍然有效。 –

+0

這就是我想聽到的 - 純粹的運氣。謝謝! – Pablo