據我所理解
int* p = new int();
有點像用建構式創建一個 int 。如果是這樣,為什么下面的代碼像陣列一樣作業?
int* p = new int();
*p = 5;
p[1] = 15;
for (int i = 0; i < 2; i )
cout << p[i] << endl;
5
15
uj5u.com熱心網友回復:
為什么 new int() 像 C 中的陣列一樣作業?
p[1]
等價于*(p 1)
,它只是取消參考指標以訪問存盤在它指向的記憶體位置中的值,該符號類似于陣列符號,它是允許的,并且比指標符號更可取,因為它更具可讀性。
據我所理解
int* p = new int();
類似于
int
使用建構式創建一個。
是的,但這還不是全部,您還為一個分配記憶體int
并將記憶體地址分配給指標p
。
請注意,它可能是int* p = new int[2]
,它是完全相同的指標,但在這種情況下,回傳的記憶體塊new
適用于 2int
而不僅僅是一個,順便說一句,這將使您的其余代碼有效,除了您沒有delete
分配的記憶體new
,這將導致記憶體泄漏。
現在考慮以下代碼:
int arr[10];
int* p = arr;
在這種情況下,您擁有完全相同的指標,但它將指向具有自動存盤持續時間的陣列的第一個元素。
指標不知道它指向多少記憶體,因為它指向給定記憶體塊中的第一個元素,對于程式來說,該塊有多大并不明顯。索引指標時,程式員有責任不超出該記憶體。
需要注意的重要一點是,在某些情況下,其他語言可能會阻止您涉足它,而 C 不會,它相信程式員會生成正確的代碼,這就是為什么成為 C 程式員通常更難的原因。
正如已經指出的那樣,您的程式在訪問p[1]
. 請注意鏈接資源的第一句話,它簡單地說:
[未定義行為]如果違反了語言的某些規則,整個程式將變得毫無意義
在這種情況下,您正在訪問的記憶體位于手動記憶體分配定義的范圍之外。輸出是您所期望的事實是(我會說很糟糕)運氣的問題,它可能今天輸出正確的結果,明天崩潰,誰知道呢。
您可以從上面的示例中看到這種情況很難診斷,這與 3 個樣本案例的型別完全相同。
無論如何,有一些方法可以診斷出這樣的記憶體問題,例如valgrind和gcc address sanitizer等。
附帶說明,避免使用原始指標,盡可能使用智能指標或C 容器之一。
我還鼓勵您獲得一些有關OOP RAII 原則相關主題的知識。
uj5u.com熱心網友回復:
為什么下面的代碼像陣列一樣作業?
它沒有。該程式具有未定義的行為,這意味著即使它沒有明確說明并且“似乎正在作業”,它仍然是錯誤的。這是由于在您的程式中p[1]
使用了運算式。p[i]
未定義的行為意味著任何事情1都可能發生,包括但不限于給出預期輸出的程式。但永遠不要依賴(或基于)具有未定義行為的程式的輸出。該程式可能會崩潰。
所以你看到的輸出(也許看到)是未定義行為的結果。正如我所說,不要依賴具有 UB 的程式的輸出。該程式可能會崩潰。
因此,使程式正確的第一步是洗掉 UB。只有這樣,您才能開始推理程式的輸出。
1有關未定義行為的更技術上準確的定義,請參見此處提到:對程式的行為沒有限制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/480187.html