2011-06-28 69 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