我是編程新手,目前正在研究地址型別轉換。我似乎不明白為什么我會得到這個:*** stack smashing detected ***: terminated Aborted (core dumped)當我運行以下代碼時?
#include<iostream>
using namespace std;
void updateValue(int *p){
*p = 610 % 255;
}
int main(){
char ch = 'A';
updateValue((int*)&ch);
cout << ch;
}
以下是我對代碼的理解:
的地址ch被型別轉換int*并傳遞給函式updateValue()。現在,在updateValue()堆疊內部,p創建了一個指向ch. 當 p 被取消參考時,它解釋ch為 anint并讀取 4(或 8)位元組的連續記憶體而不是 1。因此,'A'(65)以及一些垃圾值被分配給610%5即 20。
但我不明白,什么地方出了問題?
uj5u.com熱心網友回復:
但我不明白,什么地方出了問題?
在這份宣告中
*p = 610 % 255;
不屬于 char 型別的物件 ch 的記憶體將被覆寫。也就是說,物件 ch 占用的不是一個位元組,而是覆寫了 4 個位元組,這些位元組對應于為 int 型別的物件分配的記憶體。
uj5u.com熱心網友回復:
當 p 被取消參考時,它解釋...
當您通過重新解釋間接p并訪問錯誤型別的物件時,程式的行為是未定義的。
什么地方出了問題?
當您將指向一種型別的指標重新解釋為指向不相關型別的指標時,事情就開始出錯了。
一些經驗法則:
- 在您知道它的作用之前,不要使用重新解釋強制轉換。它們很難正確處理,而且很少有用。
- 當它會導致未定義的行為時,不要使用重新解釋強制轉換。
- 根本不要使用 C 風格的演員表。
- 如果你認為你需要重新解釋演員表,那么退后幾步,想想你為什么認為你需要它。
uj5u.com熱心網友回復:
問題是您將a型別轉換char*為 anint*然后取消參考p,這會導致未定義的行為。
未定義的行為意味著任何事情1都可能發生,包括但不限于給出預期輸出的程式。但永遠不要依賴(或基于)具有未定義行為的程式的輸出。該程式可能會崩潰。
所以你看到的輸出(也許看到)是未定義行為的結果。正如我所說,不要依賴具有 UB 的程式的輸出。該程式可能會在您的情況下發生崩潰。
例如,這里程式崩潰了,但這里沒有崩潰。
因此,使程式正確的第一步是洗掉 UB。只有這樣,您才能開始推理程式的輸出。
1有關未定義行為的更技術上準確的定義,請參見此處提到:對程式的行為沒有限制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/430724.html
