存儲器引用錯誤例
回答
我相信(告訴我,如果我錯了),因爲結構被存儲爲一件大事,引用超出範圍的數組索引將調出結構中下一個元素的數據。
在內存中,有一個int,另一個int,然後是一個double。它們全都相鄰存放。
讓我們舉個簡單的例子:
typedef struct {
int X[2];
int Y;
} struct_t;
如果我們訪問元素#3(X [2])的struct的,我們會得到Y,就像這樣:
void main() {
volatile struct_t s;
s.X[0] = 99;
s.X[1] = 98;
s.Y = 97;
printf("%i", s.X[2]);
}
該輸出97,因爲struct_t的第三個int大小的塊是97.
現在讓我們看看你的問題。 struct_t的前四個字節屬於int數組。最後八個屬於雙。 fun()
將最後八個設置爲3.14,根據我的編譯器,它等於0x51EB851F。然後它將A的第I個字節設置爲0x4000。因此,通過寫入「第三個」數組元素(與double重疊)。這將覆蓋double,並改變它的值。
通過寫入第6個字節,您開始寫出內存不足,這給您段錯誤。不過,GCC有另一個怪癖。 CPU可以更快地訪問偶數地址上對齊的數據,因此GCC會將填充插入到結構中。另外,int
和double
的大小也會隨着系統的不同而變化,這使得本例在不同的系統上輸出不同的東西。
從會計觀點來看,您沒有關閉,而是從您調用的C標準觀點*未定義行爲*嘗試訪問定義範圍之外的數組元素。 –
這是真的。 CSAPP課程正在訪問一個超出界限的數組來展示一個觀點,並且可能不是旨在鼓勵導致未定義行爲的代碼(至少,我希望如此)。 –
未定義的行爲通常在stackoverflow中被忽視。我認爲這有點失控,這是一個完全教育的例子,只要你添加免責聲明,不同的系統可能會表現出不同的行爲,並且解釋顯示在特定情況下發生了什麼 – Leeor
- 1. 無效存儲器引用(SIGSEGV)錯誤
- 2. 存儲器錯誤
- 3. MongoDB - 存儲引擎錯誤
- 4. 從存儲引擎得到錯誤-1
- 5. Mysql'從存儲引擎出現錯誤-1'錯誤
- 6. MySQL錯誤:「1030 - 遇到錯誤-1從存儲引擎」
- 7. Oracle共享存儲器錯誤
- 8. Boost ::信號存儲器訪問錯誤
- 9. Sklearn高斯迴歸 - 存儲器錯誤
- 10. LINQ到存儲過程的「錯誤的存儲屬性」錯誤
- 11. 對象引用一個未保存的瞬態實例錯誤
- 12. 錯誤:對象引用未保存的瞬態實例
- 13. JVM崩潰,錯誤= '無法分配存儲器'(錯誤= 12)
- 14. C++:右值引用存儲器
- 15. 如何在SQLCLR存儲過程中保存webservice引用實例?
- 16. 編程接收到的信號SIGSEGV:分段錯誤 - 無效的存儲器引用。 Backtrace爲這個錯誤:
- 17. Azure存儲Blob -com.microsoft.azure.storage.core.Utility錯誤
- 18. Xcode存儲Git錯誤
- 19. Oracle:存儲過程錯誤
- 20. MySQL存儲過程錯誤
- 21. MySQL存儲過程錯誤
- 22. JBoss本地存儲錯誤
- 23. 錯誤數據存儲
- 24. MySQL存儲過程錯誤
- 25. 本地存儲錯誤
- 26. 部署prestashop存儲錯誤
- 27. 存儲過程的錯誤
- 28. 會話存儲錯誤只
- 29. SQL存儲過程錯誤
- 30. ADO.NET存儲過程錯誤
在本例中考慮int的sizeof,double的sizeof以及保證可寫的內存。 –
你真正的問題是什麼?你不明白什麼? –
'double fun(int i){if(i < 0 || i > 1){.. handle error ..} ...}'? –