【零基礎學C語言】知識總結(jié)十一:動態(tài)內(nèi)存分配!

動態(tài)內(nèi)存分配(動態(tài)存儲期)
在程序執(zhí)行并使用該變量的時候分配內(nèi)存空間,使用完畢立即釋放.
動態(tài)內(nèi)存分配就 是指在程序執(zhí)行的過程中動態(tài)地分配或者回收存儲空間的分配內(nèi)存的方法。動態(tài)內(nèi)存分配不像數(shù)組等靜態(tài)內(nèi)存分配方法那樣需要預先分配存儲空間,而是由系統(tǒng)根據(jù) 程序的需要即時分配,且分配的大小就是程序要求的大小。
當程序運行到需要一個動態(tài)分配的變量或?qū)ο髸r,必須向系統(tǒng)申請取得堆中的一塊所需大小的存貯空間,用于存貯該變量或?qū)ο?。當不再使用該變量或?qū)ο髸r,也就是它的生命結(jié)束時,要顯式釋放它所占用的存貯空間,這樣系統(tǒng)就能對該堆空間進行再次分配,做到重復使用有限的資源。
在使用數(shù)組的時候,總有一個問題困擾著我們:數(shù)組應該有多大?在很多的情況下,你并不能確定要使用多大的數(shù)組,比如上例,你可能并不知道我們要定義的這個數(shù)組到底有多大,那么你就要把數(shù)組定義得足夠大。這樣,你的程序在運行時就申請了固定大小的你認為足夠大的內(nèi)存空間。

即使你知道你想利用的空間大小,但是如果因為某種特殊原因空間利用的大小有增加或者減少,你又必須重新去修改程序,擴大數(shù)組的存儲范圍。這種分配固定大小的內(nèi)存分配方法稱之為靜態(tài)內(nèi)存分配。但是這種內(nèi)存分配的方法存在比較嚴重的缺陷,特別是處理某些問題時:在大多數(shù)情況下會浪費大量的內(nèi)存空間,在少數(shù)情況下,當你定義的數(shù)組不夠大時,可能引起下標越界錯誤,甚至導致嚴重后果。
我們用動態(tài)內(nèi)存分配就可以解決上面的問題. 所謂動態(tài)內(nèi)存分配就是指在程序執(zhí)行的過程中動態(tài)地分配或者回收存儲空間的分配內(nèi)存的方法。動態(tài)內(nèi)存分配不象數(shù)組等靜態(tài)內(nèi)存分配方法那樣需要預先分配存儲空間,而是由系統(tǒng)根據(jù)程序的需要即時分配,且分配的大小就是程序要求的大小。
從以上動、靜態(tài)內(nèi)存分配比較可以知道動態(tài)內(nèi)存分配相對于靜態(tài)內(nèi)存分配的特點:
1、不需要預先分配存儲空間;
2、分配的空間可以根據(jù)程序的需要擴大或縮小。
常見的動態(tài)內(nèi)存錯誤:
(1)對NULL指針進行解引用操作
(2)對分配的內(nèi)存進行操作時越過邊界
(3)釋放并非動態(tài)分配的內(nèi)存
(4)試圖釋放一塊動態(tài)分配的內(nèi)存的一部分以及一塊內(nèi)存被釋放之后被繼續(xù)使用。
說明:
1、動態(tài)分配最常見的錯誤就是忘記檢查所請求的內(nèi)存是否成功分配。
2、動態(tài)內(nèi)存分配的第二大錯誤來源是操作內(nèi)存時超出了分配內(nèi)存的邊界。
當你使用free時,可能出現(xiàn)各種不同的錯誤:
1、傳遞給free的指針必須是一個從malloc、calloc或realloc函數(shù)返回的指針。
2、傳遞給free函數(shù)一個指針,讓它釋放一塊并非動態(tài)分配的內(nèi)存可能導致程序立即終止或在晚些時候終止。
3、試圖釋放一塊動態(tài)分配內(nèi)存的一部分也有可能引起類似問題。
const 函數(shù)(補充)
? ? ? 之前一直把這個關(guān)鍵字漏掉了現(xiàn)在補上,const 限定符,它把一個對象轉(zhuǎn)換成一個常量,C語言中const關(guān)鍵字是constant的縮寫,通常翻譯為常量、常數(shù)等,有些朋友一看到const關(guān)鍵字馬上就想到了常量。事實上在C語言中const功能很強大,它可以修飾變量、數(shù)組、指針、函數(shù)參數(shù)等。
1、修飾變量:
在程序中使用const修飾變量,就可以對變量聲明為只讀特性,并保護變量值以防被修改。如下:
const int i = 5;? 變量i具有只讀特性,不能夠被更改;若想對i重新賦值,如i = 10;則是錯誤的。
值得注意的是,定義變量的同時,必須初始化。定義形式也可以寫成int const i=5,同樣正確。
此外,const修飾變量還起到了節(jié)約空間的目的,通常編譯器并不給普通const只讀變量分配空間,而是將它們保存到符號表中,無需讀寫內(nèi)存操作,程序執(zhí)行效率也會提高。
2、修飾數(shù)組
C語言中const還可以修飾數(shù)組,舉例如下:
const int array[5] = {1,2,3,4,5};
array[0] = array[0]+1; //錯誤
數(shù)組元素與變量類似,具有只讀屬性,不能被更改;一旦更改,如程序?qū)箦e。
3、修飾函數(shù)參數(shù)
const關(guān)鍵字修飾函數(shù)參數(shù),對參數(shù)起限定作用,防止其在函數(shù)內(nèi)部被修改。所限定的函數(shù)參數(shù)可以是普通變量,也可以是指針變量。舉例如下:
void fun1(const int i)
i++; //對i的值進行了修改,程序報錯
void fun2(const int *p)
(*p)++; //對p指向空間的值進行了修改,程序報錯
保護數(shù)組中的元素:
為了避免函數(shù)的意圖不是為了修改數(shù)組當中的數(shù)據(jù)內(nèi)容,那么在函數(shù)原始聲明定義中時應使用關(guān)鍵字const,如:
int sum(const a[ ],int n);? 這段代碼告訴編譯器,該函數(shù)不能修改a所指向的數(shù)組中的內(nèi)容,如果在函數(shù)中不小心使用類似a[i]++;的表達式,那么程序?qū)箦e。
要注意的是,這樣使用const并不是要求原數(shù)組是常量,而是該函數(shù)在處理數(shù)組時將其視為常量,不可修改,這樣使用const可以保護數(shù)組當中的數(shù)據(jù)不被修改。
4、修飾指針
C語言中const修飾指針要特別注意,共有兩種形式,一種是用來限定指向空間的值不能修改;另一種是限定指針不可更改。舉例說明如下:
int i = 5;
int j = 6;
int k = 7;
const int * p1 = &i; //定義1
int * const p2 =&j; //定義2
上面定義了兩個指針p1和p2。
在定義1中const限定的是 * p1,即其指向空間的值不可改變,若改變其指向空間的值如*p1=20,則程序會報錯;但p1的值是可以改變的,對p1重新賦值如p1=&k是沒有任何問題的。
在定義2中const限定的是指針p2,若改變p2的值如p2=&k,程序?qū)箦e;但*p2,即其所指向空間的值可以改變,如 * p2=80是沒有問題的,程序正常執(zhí)行。
關(guān)于指針賦值和const需要注意一些規(guī)則:
1、把const數(shù)據(jù)或非const數(shù)據(jù)的地址初始化為指向const的指針或為其賦值是合法的
2、可以聲明并初始化一個不能指向別處的指針,關(guān)鍵是const的位置,這時候,這個指針可以修改它所指向的值,但是只能指向初始化時設置的地址。
3、在創(chuàng)建指針時還可以使用兩次const,表示該指針既不能修改它所指向的地址,也不能修改它所指向地址上的值
清單:
塊
塊指的是一塊數(shù)據(jù),是個抽象的概念,和C語言沒有關(guān)系,這種抽象的東西,別說其他語言也能用,就是日常生活中也會把東西分塊管理,C語言中沒有對塊進行定義,因為這只是個抽象的概念,塊可以是內(nèi)存塊,數(shù)據(jù)塊,程序塊,哪怕是豆腐塊也能是塊...? 意思就是在管理中被劃分為一類的一個基本單位
存儲期:
存儲期這也是變量的特點,它稱為生存期,表示變量在內(nèi)存中存在的時間的長短。
? 1、靜態(tài)存儲期:在程序編譯時就分配內(nèi)存空間并保持不變,程序執(zhí)行結(jié)束后才釋放。
? 2、線程存儲期:thread_local,其聲明后會給每個線程分配一個單獨的私有備份
? 3、自動存儲期:局部變量通常都自動為auto 存儲期
? 4、動態(tài)存儲期:就是用new 或者malloc分配的內(nèi)存,如果不主動釋放,在整個程序都占有內(nèi)存
作用域:
這個是表示變量在哪些范圍內(nèi)起作用,由鏈接點決定。
1、塊作用域:用{}括起來的,從聲明開始到“}” 結(jié)束
? ? 2、函數(shù)作用域:goto(標識符) 的作用域為整個函數(shù)。
? ? 3、函數(shù)原型作用域:函數(shù)聲明開始,函數(shù)聲明結(jié)束而結(jié)束
? ? 4、文件作用域:整個文件或者程序
鏈接屬性:表示變量能在哪些范圍內(nèi)使用.
1、內(nèi)部鏈接 :只能在源文件內(nèi)部使用.
2、外部鏈接 : 能在源文件內(nèi)部和外部文件中使用.
3、空連接 : 只能在代碼塊內(nèi)(函數(shù)內(nèi)部)使用.
限定符:
? volatile:
? const:
? restrict:
_Atomic:

作者:Mr_Li_
另外的話為了幫助大家,輕松,高效學習C語言/C++,我給大家分享我收集的資源,從最零基礎開始的教程到C語言項目案例,幫助大家在學習C語言的道路上披荊斬棘!
微信公眾號:C語言編程學習基地
整理分享(多年學習的源碼、項目實戰(zhàn)視頻、項目筆記,基礎入門教程)最重要的是你可以在群里面交流提問編程問題哦!

歡迎轉(zhuǎn)行和學習編程的伙伴,利用更多的資料學習成長比自己琢磨更快哦!大家也要把握住有限的時光,抓住成長的每一次機會哦~
編程學習視頻分享:
