铸造地址(id)是否有副作用? 地址0xbfffe8d0是否特殊? (修正:问题是与_NSCallStackArray)

下面的代码行导致我的程序以非常奇怪的方式破解…

id foo = (id)0xbfffe8d0; 

然而,这不是问题:

 int foo = (int)(id)0xbfffe8d0; 

而且即使这是没有问题的:

 int magicAddr = 0xbfffe8d0; id foo = (id)magicAddr; 

WTF?

只要在特定的init方法中插入这行代码,就会导致我的迭代通过一个数组失败,并发生“NSGenericException:集合被枚举时发生了变化”。 注释该行将导致exception不会发生。 这个代码是单线程的。 这个行为是确定性的,并且在我评论此行时,一再重复,一贯地不再转载。 “foo”是一个组成的variables,不会再被引用。 没有其他代码引用“富”。

这条线是否有副作用? 给一个(id)投个数有没有副作用?

关于我在做什么的更多细节:

  • 我运行NSLog(@“self =%p,super =%p”,self,super),并打印出“self = 0xa83dc50,super = 0xbfffe8d0”,引导我提出这个问题
  • 我有_NO_IDEA_ 0xbfffe8d0值是什么意思。
  • 我粘贴的行是在一个类的init2方法内部,该引用通过抛出exception的集合引用NSEnumerator。 该类不改变集合,甚至没有对集合的引用。

确切的代码:(删除,不相关或有趣)


好的,所以我仍然无法解释上面的行为。 我无法解释为什么堆栈中的4字节int是可以的,但是4字节的“id”是crashville。 但是我把这个代码运行了几百次,把所有的随机垃圾都放进去了,而且我还能用其他的价值观和陈述来触发崩溃。 总是确定性的,但没有明确的或可解释的模式的东西坠毁与没有的东西。 Bizzare的东西,但不是最终的问题。

真正的问题? 收集来自[NSThread callStackSymbols]。 这返回_NSCallStackArray。 这就是真正的斑马生活的地方。 关于这个伪集合有些东西,但我不能告诉你究竟是什么。

修复?

 [NSArray arrayWithArray: [NSThread callStackSymbols]] 

随着修复,我的代码中没有随机废话的组合将触发枚举崩溃。 所以要小心。 如果您打算返callback用堆栈符号并将它们视为数组,请进行复制。

课程? 如果您调用[NSThread callStackSymbols],并想要像数组一样处理结果,请进行复制并获得真实数组。 否则,….“有龙”!

No. id是一个指针types的typedef ,分配给一个指针没有副作用。 你的代码中还有其他一些bug,如果没有看到更多的代码就说不出来。

0xbfffe8d0是指向堆栈中的地址的指针。 当没有优化编译时,赋值确实将值0xbffe8d0写入到堆栈中,但是那个值永远不会被读取到任何地方。 所以它确实具有(a)将该函数的堆栈帧大小增加4个字节的效果,以及(b)改变该函数的代码的大小并抵消所有随后的代码。 这些更改很可能导致程序中其他位置的错误出现或不出现。