2012-04-01 64 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

相關問題