将地址转换为(id)有副作用吗???地址0xbfffe8d0特殊吗?(已修复:_NSCallStackArray出现问题



下面的代码行导致我的程序以一种非常奇怪的方式中断。。。

id foo = (id)0xbfffe8d0;

然而,这不是问题:

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

即使这样也没问题:

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

W。T.F?

只要在特定的init方法中插入这行代码,就会导致我通过数组的迭代失败,并显示"NSGenericException:枚举时集合发生了变异"。注释行out会导致异常不发生。此代码是单线程的。行为是确定性的,并且一次又一次地不断重复,当我评论这条线时,一直没有重复。"foo"是一个虚构的变量,以后再也不会被引用。没有其他代码引用"foo"。

那句话有副作用吗?将数字强制转换为(id)是否有一些副作用?

关于我正在做的事情的更多细节:

  • 我运行了NSLog(@"self=%p,super=%p",self,super),它打印出"self=0xa83dc50,super=0xfffe8d0",这让我问了这个问题
  • 我有_NO_IDEA_ 0xbfffe8d0值是什么或意味着什么
  • 我粘贴的行在一个类的方法init2内,该类在引发Exception的集合上引用了NSEnumerator。该类不会更改集合,甚至不会引用集合

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


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

真正的问题是什么集合来自[NSThread callStackSymbols]。返回_NSCallStackArray。那是真正的斑马生活的地方。这个伪收藏有点古怪,但我不能告诉你具体是什么。

修复

[NSArray arrayWithArray: [NSThread callStackSymbols]]

通过修复,我的代码中没有任何随机垃圾的组合会触发枚举崩溃。所以要小心。如果您计划返回调用堆栈符号并将其视为一个数组,请进行复制。

教训如果您调用[NSThread callStackSymbols]并希望将结果视为一个数组,请进行复制并获得一个真实的数组。其他的"那里有龙"!!

否。id是指针类型的typedef,分配给指针没有副作用。你的代码在其他地方有其他错误,如果没有看到更多的代码,就不可能说出来。

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

最新更新