簡體   English   中英

分段錯誤和字符指針和 int ponter

[英]segmentation fault and char pointer and int ponter

代碼1:



char *pc = "abc";     
cout<<*pc<&ltendl;

代碼2:



int *pi = 10 ;
cout<<*pi<&ltendl;

為什么code1提示warn信息為“warning: deprecated conversion from string constant to 'char*'”; 但是code2提示錯誤消息為“錯誤:從 'int' 到 'int*' 的無效轉換”。

【Q1】據我觀察,它們都是不匹配的,但為什么一個得到警告,另一個得到錯誤?

當我嘗試解決這個問題時:

代碼3:



int *pi = (int*)10 ;  //compile correctly without error
cout<<*pi<&ltendl;      //get "segmentation fault"

代碼4:



char *pc = (char*)"abc";  //compile without warning    
cout<<*pc<&ltendl;         // output 'a'

【Q2】為什么cout<<*pi<< endl; 在代碼 3 中得到分段錯誤並且代碼 4 中的cout<<*pc<< endl運行正確嗎?

這似乎是一個受歡迎的問題,但對差異的解釋很少。 有人可以幫我嗎?

提前致謝。

  1. 嘗試:

     const char *pc = "abc"; cout << pc << endl;
  2. 嘗試:

     int pi = 10; cout << pi << endl;

在上述情況 1 中,字符串文字的類型為 const char *

在第 2 種情況下,您聲明的不是整數,而是整數指針,並將 ADDRESS 10 分配給該指針,然后嘗試取消引用它(實際上您試圖訪問內存地址 10 處的數據,您可能沒有訪問,這就是您崩潰的原因)

雖然語法可能很危險,但這里的 foo 確實指向內存中的一個有效位置——它是一個指向“abc”(也稱為“a”)開頭的字符指針:

char *foo = "abc";

但在這里:

int *pi = (int*)10 ;  //compile correctly without error
cout<<*pi<<endl;

pi 指向內存地址 10,這很好,直到您嘗試尊重它 - 這是一個很大的禁忌,因為您的程序無法訪問該內存。

char *pc = "abc";

“abc”就是所謂的字符串文字。 正如您所知,它可能不會存儲在內存中,並且可能無法更改。 試圖,例如

pc[1] = 'k';

將產生不可預測的結果,很可能會導致程序崩潰,因為該位置無法寫入。

編譯器警告告訴您,您正在將一個指針分配給一個您不能或不應更改為允許您更改該值的指針的值。 此處的快速修復是通知編譯器您不會嘗試更改“abc”並接受編譯器的打擊(如果您嘗試)。

const char *pc = "abc";

寫入pc引用的內存現在會生成編譯器警告,但比寫入無效內存的程序做一些奇怪的事情要好。

這是一個警告而不是一個錯誤,因為有大量古老的代碼執行這種有風險的常量->非常量賦值,但從不嘗試寫入不可寫的位置,如果這是一個錯誤,它將停止編譯。 現在,編譯器只需標記問題並建議您修復它。

這段代碼:

char *pc = (char*)"abc";  
cout<<*pc<<endl;         

不會崩潰,或以其他方式表現出不良行為,因為保存“abc”的位置是可讀的。

char *pc = (char*)"abc";  
cin >>*pc;         

如果不是立即致命,那將是非常糟糕的。

另一方面,

int *pi = 10 ;

有點不同。 它生成一個指向內存位置 10 處的整數的指針,這幾乎肯定是錯誤的。 char *pc = "abc"; 存在風險,嘗試使用尚未分配給程序的內存位置是不好的,並且可能是致命的。 你希望它是致命的,因為另一種選擇是“伙計,我的數據在哪里?”的不那么有趣的游戲。 指針不是整數,不管你被告知什么,這會產生一個錯誤迫使程序員在做一些愚蠢的事情之前至少要三思。

在驅動程序和嵌入式編程中存在一些例外,其中直接硬件訪問是常見的,但這些是通過強制轉換和其他技巧指定的,以確保編譯器知道您在做什么,並且在指定地址確實存在可訪問的內容。 正是你在這里所做的:

int *pi = (int*)10 ;

但是當您嘗試打印它時程序會崩潰,因為您的程序在地址 10 處沒有分配和可訪問的內容。正如您所見,這被認為是一個錯誤,這是有充分理由的。 您既不能讀也不能寫,因此它不會獲得編譯器為可讀但不可寫的“abc”提供的條件傳遞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM