在準備期末考試時,我偶然發現了以下問題:鑒于這段代碼:
#include <stdio.h>
int main() {
const char *const ptr1[] = {"to be", "or not to be", "that is the question"};
char *ptr2 = "that is the question";
(&ptr2)[3]="hamlet";
for (int i = 0; i < sizeof(ptr1) / sizeof(*ptr1); i)
printf("%s ", ptr1[i]);
return 0;
}
列印以下內容:“成為小村莊就是問題”
我認為這段代碼不會編譯。
但是,代碼可以編譯。
有人可以幫我理解為什么這段代碼會這樣嗎?
uj5u.com熱心網友回復:
它可能會編譯,因為代碼中沒有任何內容需要編譯器來診斷問題。
分配在型別正確的意義上起作用。ptr2有 type char*,所以&ptr2有 typechar**和(&ptr2)[3]有 type char*,我們可以分配一個字串文字。
但是,ptr2它不是陣列,因此3無法在偏移量處訪問它。該程式具有未定義的行為,宣告特定輸出沒有意義。
編譯程式時啟用警告和消毒劑,看看有什么問題:https : //godbolt.org/z/G67j6qr7a
uj5u.com熱心網友回復:
代碼可以編譯,就 C 語言語法和約束而言,賦值本身是有效的。但是,它會呼叫未定義的行為(請參閱什么是未定義的行為以及它是如何作業的?),因為您ptr2越界訪問變數- 這是無稽之談。我沒有得到你在我的編譯器上宣告的輸出,僅僅是因為這段代碼沒有確定性的結果。
在某些系統上,越界訪問可能會生成對堆疊上先前宣告的陣列的訪問,但不能保證這種行為。大多數系統都有向下計數的堆疊,所以我認為它們中的很多最終不會像假設的那樣修改指標陣列。此外,編譯器可以自由分配ptr1并ptr2在彼此相關的任何地址上。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/407505.html
標籤:
上一篇:NoSuchMethodError:com.sun.mail.util.TraceInputStreamTomcat9jdk1.8.0_281
