偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

EasyC++16,指針初探之二

開發(fā) 后端
指針由于能夠操作內(nèi)存,所以如果使用的時候不夠仔細(xì),很容易引發(fā)一些意想不到的錯誤。

[[431850]]

大家好,我是梁唐。

想要追求更好閱讀體驗的同學(xué),可以點擊文末的「閱讀原文」,訪問github倉庫。

危險的case

指針由于能夠操作內(nèi)存,所以如果使用的時候不夠仔細(xì),很容易引發(fā)一些意想不到的錯誤。

C++ Primer當(dāng)中給了這樣一個例子:

  1. int *ptr; 
  2. *ptr = 2333; 

在這段代碼當(dāng)中我們聲明了一個int型的指針,并且將它指向了2333。然而,這里有一個問題,我們在聲明指針的時候并沒有進(jìn)行初始化。沒有初始化的指針并不為空,而是指向一個未知的地方。如果說它指向的是一個常量1200的地址,我們讓它等于2333,那么之后當(dāng)我們使用1200這個常量的時候,得到的結(jié)果都是2333。

更可怕的是,整個過程非常地隱蔽,很難察覺。debug的時候會令人抓狂。

所以千萬不要修改一個沒有初始化的指針指向的值。

指針和數(shù)字

C++ Primer當(dāng)中還給了另外一個例子,當(dāng)我們輸出指針的時候,得到的是一串十六進(jìn)制的數(shù)。那我們能不能反過來將一個十六進(jìn)制的數(shù)賦值給指針呢?

  1. int *p; 
  2. p = 0xB8000000; 

答案是不行,因為類型不一致。雖然我們打印指針的時候看起來得到是十六進(jìn)制數(shù),但它的類型其實是指針類型,而不是整數(shù)類型。所以我們將一個整數(shù)賦值給一個指針是不行的,如果非要賦值,必須要進(jìn)行類型轉(zhuǎn)換。

  1. int *p; 
  2. p = (int*) 0xB8000000; 

但是這一轉(zhuǎn)換之后顯然又出現(xiàn)了一個問題,我們知道0xB8000000這個地址指向哪里么?顯然不知道,自然也就說不清改了這里的值之后會引發(fā)什么結(jié)果。

所以雖然這么做可行,但也強烈不建議這樣干。

new操作

前文說過使用指針有一個非常大的好處就是可以在程序運行的時候,動態(tài)分配內(nèi)存。其實在C語言當(dāng)中也有類似的功能,可以使用malloc來分配內(nèi)存。不過在C++當(dāng)中有了更好用的運算符——new。

比如我們要動態(tài)創(chuàng)建一個int類型的變量,可以這樣寫:

  1. int *ptr = new int

new運算符根據(jù)之后的類型確定需要的內(nèi)存大小,找到這樣的內(nèi)存之后,返回地址。剛好指針接收的值就是內(nèi)存地址,因此剛好可以完成這樣的賦值操作。

上面的代碼也可以寫成這樣:

  1. int a; 
  2. int *ptr = &a; 

這兩者有什么區(qū)別呢?表面上看沒有區(qū)別,都是創(chuàng)建了一個int類型的變量。只不過第二種寫法除了可以使用指針ptr之外,還可以使用變量名a來訪問這個int。

但實際上這兩者的內(nèi)部實現(xiàn)完全不同,我們直接通過變量名創(chuàng)建的變量它的值會被存儲在棧內(nèi)存當(dāng)中,而通過new創(chuàng)建的對象則被存儲在堆內(nèi)存當(dāng)中。棧內(nèi)存是由系統(tǒng)自動分配,而堆內(nèi)存則是由程序員進(jìn)行申請使用。這兩者的內(nèi)存模型是完全不同的,我們會在之后的文章詳細(xì)地討論這點。目前簡單來理解的話,就是堆內(nèi)存更加靈活,它的空間也更大,可以存儲下更大的數(shù)據(jù)。

delete操作

有了動態(tài)創(chuàng)建,自然也就有動態(tài)刪除,所以C++當(dāng)中有一個delete操作和new相對應(yīng)。

delete運算符可以在變量使用結(jié)束之后,將內(nèi)存歸還給內(nèi)存池。因為很多時候程序當(dāng)中的變量都是一次性使用或者是有生命周期的,當(dāng)生命周期結(jié)束,使命完成就沒有必要繼續(xù)占用著資源了。畢竟系統(tǒng)內(nèi)的內(nèi)存資源是有限的,尤其是在一些大型項目或者嵌入式系統(tǒng)當(dāng)中,內(nèi)存資源非常緊張。

delete運算符之后跟一個指針,它會釋放改指針指向的內(nèi)存。

  1. int *ptr = new int
  2. delete ptr; 

這里面有很多坑,千萬要當(dāng)心。首先是使用了new創(chuàng)建了內(nèi)存之后,一定要記得delete,否則這塊內(nèi)存將會永遠(yuǎn)被占用無法得到釋放,這種情況被稱為內(nèi)存泄漏(memory leak)。另外,我們不能delete一個已經(jīng)delete過的指針,這也會引發(fā)嚴(yán)重錯誤。C++ Primer對此的描述是:什么情況都可能發(fā)生。當(dāng)然也不能再使用一個已經(jīng)被delete的指針,這會引發(fā)空指針錯誤。

指針對于C++來說是一把雙刃劍,像是Java、Python、Go等其他語言,內(nèi)存回收的工作都是由系統(tǒng)自動執(zhí)行的。例如Java的JVM虛擬機設(shè)計了嚴(yán)密的GC(垃圾回收)機制,程序員無須關(guān)心內(nèi)存的回收問題,全部交給程序自動完成。

 

而在C++當(dāng)中,這一過程是由程序員手動執(zhí)行的,某種程度上來說,這當(dāng)然非常好,程序員擁有了很高的權(quán)限以及靈活度。但同樣也是一個坑,尤其是在復(fù)雜系統(tǒng)當(dāng)中,很難準(zhǔn)確判斷delete執(zhí)行的時間。這會引發(fā)嚴(yán)重的問題,例如內(nèi)存泄漏嚴(yán)重,野指針到處飛等……

 

責(zé)任編輯:武曉燕 來源: Coder梁
相關(guān)推薦

2021-10-27 16:27:20

C++指針操控

2021-10-29 09:44:50

C++指針變量

2021-12-12 18:13:54

C++This指針

2021-10-26 00:19:51

C++結(jié)構(gòu)體存儲

2021-11-09 10:38:16

C++Const指針

2021-11-10 10:48:36

C++函數(shù)指針

2021-12-29 20:31:40

C++多態(tài)指針

2021-11-26 00:03:20

C++編譯常量

2021-12-09 10:56:50

函數(shù)C++原型

2021-12-08 10:43:09

C++實現(xiàn)

2021-12-10 10:45:36

C++函數(shù)Stock

2021-12-30 14:58:58

C++函數(shù)動態(tài)

2021-12-11 19:02:03

函數(shù)C++對象

2021-11-27 11:50:09

C++靜態(tài)持續(xù)

2021-12-20 21:01:52

鴻蒙HarmonyOS應(yīng)用

2021-10-26 15:36:17

C++枚舉值類型

2021-12-05 18:20:42

C++空間特性

2021-12-15 10:25:57

C++運算符重載

2022-01-04 16:35:42

C++Protected關(guān)鍵字

2021-10-21 18:52:00

C++數(shù)組存儲
點贊
收藏

51CTO技術(shù)棧公眾號