2012-04-01 33 views
3

下面的代码行导致我的程序在一个非常奇怪的方式打破...是否投送地址(id)有副作用?地址0xbfffe8d0是否特殊? (固定:问题是与_NSCallStackArray)

id foo = (id)0xbfffe8d0; 

然而,这是没有问题的:

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

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

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

WTF?

只需在特定的init方法内插入该行代码就会导致我对数组的迭代失败,导致“NSGenericException:集合在枚举时发生了变化”。注释该行会导致异常不会发生。此代码是单线程的。这种行为是确定性的,并且在我评论该行时,一再重复并一致地不再转载。 “foo”是一个虚构的变量,不会再被引用。没有其他代码引用“foo”。

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

上我是做什么的更多细节:

  • 我跑的NSLog(@ “自我=%P,超级=%P”,自我,超),并打印出来的“自我= 0xa83dc50,超级= 0xbfffe8d0“,导致我问this question
  • 我有_NO_IDEA_什么0xbfffe8d0值是或手段。
  • 我粘贴的这行代码在一个方法init2中,该方法在引发异常的集合上引用了NSEnumerator。该类不会改变集合,甚至不会引用集合。

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


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

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

修复?

[NSArray arrayWithArray: [NSThread callStackSymbols]] 

随着修复,在我的代码没有随机掷骰子的组合将引发枚举崩溃。所以要小心。如果您打算返回调用堆栈符号并将它们视为数组,请进行复制。

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

回答

3

编号idtypedef指针类型,并分配给一个指针没有副作用。你的代码中还有一些其他的bug,如果没有看到更多的代码就说不出来。

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

+0

我会说你所说的所有事情,除了添加一个4字节的int导致没有问题,只有当我投给(ID).... – 2012-04-01 03:43:02

+0

好吧,你是对的。斑马在别处。尽管如此,还是有斑马...... – 2012-04-01 03:55:41

相关问题