2011-06-28 16 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]要素に割り当てられ、ブロック構造が破棄されます。問題は、2番目のループのb [i]がブロックの最後の状態への有効/同じポインタを含む理由です。要素が無効なスタック領域を指しているので、2番目のループがクラッシュすると思います。スタックブロックの寿命

私はこれが最高のコードではないことを知っています。私はそれを使用していません。しかし、なぜ最初のループの後、ブロック構造が破壊されるべきなのか理解したい、私は有効なスタックオブジェクトを持っています。

+0

関連[ブロックの字句範囲を理解できません](http://stackoverflow.com/questions/6647918/unable-to-understand-the-blocks-lexical-scope/6648368#6648368) –

答えて

2

コードが作成された範囲外のブロックを使用しているため、コードの動作が未定義です。あなたは代わりに、これを書く必要があります。それは実際には追加のconst修飾子を持つブロックのスコープにコピーされているので

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

変数が問題を引き起こすことはありません。変数にブロックへの書き込みアクセスを与えるには、変数を__block修飾子で宣言します。これは、参照ブロックのコピー時にスタックからヒープに変数を移動するという奇妙な副作用があります。

+1

私はそのブロックを知っていますスタックで起動していて、ヒープにコピーしないとスコープに制限されています。しかし、なぜポインタはまだ有効ですか? – Pablo

+0

ブロック自体以外には、ポインタは含まれていません。変数はブロックのスコープにコピーされます。ブロックのコピーを作成しないので、 'i'のコピーはスタックに残っています.2番目のループでそれを使用すると、範囲外になってもまだ動作します。 –

+0

それは私が聞きたかったものです。純粋な運があります。どうも! – Pablo

関連する問題