3 回答

TA貢獻1860條經驗 獲得超9個贊
那是因為指針的行為不像整數。這是未定義的行為,因為標準如此規定。
但是,在大多數平臺(如果不是全部)上,如果不取消引用數組,則不會崩潰或出現可疑行為。但是,如果您不取消引用它,那么進行添加有什么意義呢?
就是說,請注意,從技術上講,在數組末尾加一個表達式是100%“正確的”,并且保證不會按照C ++ 11規范的5.7節§5崩潰。但是,該表達式的結果是不確定的(只保證不會溢出);而任何其他超出數組界限的表達式都是明確的未定義行為。
注意:這并不意味著從一個以上的偏移量進行讀寫是安全的。您可能將編輯不屬于該數組的數據,并會導致狀態/內存損壞。您不會導致溢出異常。
我的猜測是這樣的,因為不僅取消引用是錯誤的。還有指針算術,比較指針等。因此,說不做而不是列舉可能存在危險的情況,更容易說。

TA貢獻1824條經驗 獲得超6個贊
原始的x86可能與此類語句有關。在16位代碼上,指針為16 + 16位。如果將偏移量添加到低16位,則可能需要處理溢出并更改高16位。那是一個緩慢的操作,最好避免。
在這些系統上,array_base+offset
如果offset在范圍內(<=數組大?。瑒t保證不會溢出。但是array+5
如果數組僅包含3個元素,則會溢出。
溢出的結果是您得到的指針不在數組的后面,而是在數組的后面。那可能甚至不是RAM,而是內存映射的硬件。如果您構造指向隨機硬件組件的指針,C ++標準不會嘗試限制發生的事情,即在實際系統上是未定義行為。

TA貢獻1834條經驗 獲得超8個贊
“未定義的行為”并不意味著它必須在該行代碼上崩潰,而是意味著您不能保證任何結果。例如:
int arr[4] = {0, 1, 2, 3};
int* p = arr + 5; // I guess this is allowed to crash, but that would be a rather
// unusual implementation choice on most machines.
*p; //may cause a crash, or it may read data out of some other data structure
assert(arr < p); // this statement may not be true
// (arr may be so close to the end of the address space that
// adding 5 overflowed the address space and wrapped around)
assert(p - arr == 5); //this statement may not be true
//the compiler may have assigned p some other value
我敢肯定,這里還有很多其他例子。
- 3 回答
- 0 關注
- 573 瀏覽
添加回答
舉報