亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么越界指針算術的行為不確定?

為什么越界指針算術的行為不確定?

C++
慕絲7291255 2019-11-20 10:16:45
以下示例來自Wikipedia。int arr[4] = {0, 1, 2, 3};int* p = arr + 5;  // undefined behavior如果我從不取消引用p,那么為什么arr + 5本身是不確定的行為?我希望指針表現為整數-例外,即在取消引用時,指針的值將被視為內存地址。
查看完整描述

3 回答

?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

那是因為指針的行為不像整數。這是未定義的行為,因為標準如此規定。

但是,在大多數平臺(如果不是全部)上,如果不取消引用數組,則不會崩潰或出現可疑行為。但是,如果您不取消引用它,那么進行添加有什么意義呢?

就是說,請注意,從技術上講,在數組末尾加一個表達式是100%“正確的”,并且保證不會按照C ++ 11規范的5.7節§5崩潰。但是,該表達式的結果是不確定的(只保證不會溢出);而任何其他超出數組界限的表達式都是明確的未定義行為。

注意:這并不意味著從一個以上的偏移量進行讀寫是安全的。您可能編輯不屬于該數組的數據,并導致狀態/內存損壞。您不會導致溢出異常。

我的猜測是這樣的,因為不僅取消引用是錯誤的。還有指針算術,比較指針等。因此,說不做而不是列舉可能存在危險的情況,更容易說。


查看完整回答
反對 回復 2019-11-20
?
慕妹3242003

TA貢獻1824條經驗 獲得超6個贊

原始的x86可能與此類語句有關。在16位代碼上,指針為16 + 16位。如果將偏移量添加到低16位,則可能需要處理溢出并更改高16位。那是一個緩慢的操作,最好避免。

在這些系統上,array_base+offset如果offset在范圍內(<=數組大?。瑒t保證不會溢出。但是array+5如果數組僅包含3個元素,則會溢出。

溢出的結果是您得到的指針不在數組的后面,而是在數組的后面。那可能甚至不是RAM,而是內存映射的硬件。如果您構造指向隨機硬件組件的指針,C ++標準不會嘗試限制發生的事情,即在實際系統上是未定義行為。


查看完整回答
反對 回復 2019-11-20
?
MMMHUHU

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

我敢肯定,這里還有很多其他例子。


查看完整回答
反對 回復 2019-11-20
  • 3 回答
  • 0 關注
  • 573 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號