最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言動態(tài)內(nèi)存分配函數(shù)的實現(xiàn)

 更新時間:2021年05月11日 08:39:54   作者:愛上小公舉  
這篇文章主要介紹了C語言動態(tài)內(nèi)存分配函數(shù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

 在C中我們開辟內(nèi)存空間有兩種方式 :

1.靜態(tài)開辟內(nèi)存 :例如:

int a;int b[10];

 這種開辟內(nèi)存空間的特點是
所開辟的內(nèi)存是在棧中開辟的固定大小的 ,如a是4字節(jié) ,數(shù)組b是40字節(jié) ,并且數(shù)組在申明時必須指定其長度 , 如果是全局數(shù)組的話,內(nèi)存是在編譯時分配好的,如果是局部變量數(shù)組的話,運行時在棧上靜態(tài)分配內(nèi)存。不管是全局數(shù)組還是局部數(shù)組,它們都有一個特點,那就是數(shù)組大小是確定的,是代碼中寫死的。那如果我們想在程序運行時才確定一個數(shù)組的大小 , 前兩種在棧上分配內(nèi)存的方法顯然是不行的 , 舉個例子 :

int n;
scanf("%d", &n);
int a[n];

這樣編寫會在編譯時出錯 , 編譯器會提醒[ ]中應(yīng)為常量表達式 , 在C中定義數(shù)組時可以用的有以下幾種 ,例:

#define N 10
enum NUM{
	M=10
};
int a1[N];
int a2[10];
int a3[M];

需要注意的是 ,C中const int n =10 ; n并不能作為數(shù)組長度定義數(shù)組 , 但C++中則可以 , 
但我們對于開辟空間的需求 , 往往不限于此 , 最常見的定義數(shù)組時數(shù)組大小在程序運行時才知道的 , 靜態(tài)開辟就已經(jīng)無能為力 . 當(dāng)然有靜態(tài)開辟 ,肯定也有動態(tài)開辟 ,接下來我們就來看動態(tài)開辟內(nèi)存空間

2.動態(tài)開辟內(nèi)存 :

在C中動態(tài)開辟空間需要用到三個函數(shù) :

malloc(), calloc(), realloc() ,這三個函數(shù)都是向堆中申請的內(nèi)存空間.
在堆中申請的內(nèi)存空間不會像在棧中存儲的局部變量一樣 ,函數(shù)調(diào)用完會自動釋放內(nèi)存 , 需要我們手動釋放 ,就需要free()函數(shù)來完成.

下面讓我們來看看這幾個函數(shù)各自的特點, 用法, 區(qū)別, 聯(lián)系.

1.malloc()

void * malloc(size_t size)

1).malloc()函數(shù)會向堆中申請一片連續(xù)的可用內(nèi)存空間
2).若申請成功 ,,返回指向這片內(nèi)存空間的指針 ,若失敗 ,則會返回NULL, 所以我們在用malloc()函數(shù)開辟動態(tài)內(nèi)存之后, 一定要判斷函數(shù)返回值是否為NULL.
3).返回值的類型為void*型, malloc()函數(shù)并不知道連續(xù)開辟的size個字節(jié)是存儲什么類型數(shù)據(jù)的 ,所以需要我們自行決定 ,方法是在malloc()前加強制轉(zhuǎn) ,轉(zhuǎn)化成我們所需類型 ,如: (int*)malloc(sizeof(int)*n).
4).如果size為0, 此行為是未定義的, 會發(fā)生未知錯誤, 取決于編譯器

具體怎么用呢 ,舉個例子 .

int *p = NULL;
int n = 0;
scanf("%d", &n);
p = (int*)malloc(sizeof(int) * n);
if(p != NULL){
    //....需要進行的操作
}

這時就相當(dāng)于創(chuàng)建了一個數(shù)組 p[n] ,這個n的值并不需要像定義一個普通數(shù)組一樣必須是常量, 可以使程序運行時得出的, 或是用戶輸入的

 2.free()

void free(void* ptr)

在堆中申請的內(nèi)存空間不會像在棧中存儲的局部變量一樣 ,函數(shù)調(diào)用完會自動釋放內(nèi)存 , 如果我們不手動釋放, 直到程序運行結(jié)束才會釋放, 這樣就可能會造成內(nèi)存泄漏, 即堆中這片內(nèi)存中的數(shù)據(jù)已經(jīng)不再使用, 但它一直占著這片空間, (通俗說就是就是占著茅坑不拉屎), 所以當(dāng)我們申請的動態(tài)內(nèi)存不再使用時 ,一定要及時釋放 .

1).如果ptr沒有指向使用動態(tài)內(nèi)存分配函數(shù)分配的內(nèi)存空間,則會導(dǎo)致未定義的行為。
2).如果ptr是空指針,則該函數(shù)不執(zhí)行任何操作。
3).此函數(shù)不會更改ptr本身的值,因此它仍指向相同(現(xiàn)在已經(jīng)無效)的位置(內(nèi)存)
4).在free()函數(shù)之后需要將ptr再置空 ,即ptr = NULL;如果不將ptr置空的話 ,后面程序如果再通過ptr會訪問到已經(jīng)釋放過無效的或者已經(jīng)被回收再利用的內(nèi)存, 為保證程序的健壯性, 一般我們都要寫ptr = NULL; . 

注意 : free()不能重復(fù)釋放一塊內(nèi)存, 如:

free(ptr);
free(ptr);

是錯的, 已經(jīng)釋放過的內(nèi)存不能重復(fù)釋放, 會出現(xiàn)內(nèi)存錯誤 .

free()具體用法, 舉個例子 :

int *p = NULL;
int n = 0;
scanf("%d", &n);
p = (int*)malloc(sizeof(int) * n);
if(p != NULL){
    //....需要進行的操作
}
//操作完成 ,不再使用這片內(nèi)存空間
free(p);
p = NULL;

 3.calloc()

void * calloc(size_t num,size_t size)

與malloc()函數(shù)的區(qū)別只在于, calloc()函數(shù)會在返回地址之前將所申請的內(nèi)存空間中的每個字節(jié)都初始化為0 .

1).calloc()函數(shù)功能是動態(tài)分配num個大小(字節(jié)長度)為size的內(nèi)存空間 .
2).若申請成功 ,,返回指向這片內(nèi)存空間的指針 ,若失敗 ,則會返回NULL, 所以我們在用calloc()函數(shù)開辟動態(tài)內(nèi)存之后, 一定要判斷函數(shù)返回值是否為NULL.
3).返回值的類型為void*型, calloc()函數(shù)雖然分配num個size大小的內(nèi)存空間 ,但還是不知道存儲的什么類型數(shù)據(jù) ,所以需要我們自行決定 ,方法是在calloc()前加強制轉(zhuǎn) ,轉(zhuǎn)化成我們所需類型 ,如: (int*)calloc(num, sizeof(int)).
4).如果size與num有一個或都為0, 此行為是未定義的, 會發(fā)生未知錯誤, 取決于編譯器

所以如何我們對申請的內(nèi)存空間的內(nèi)容要求初始化,那么可以很方便的使用calloc函數(shù)來完成這個需求。
例如 :

4.realloc()

void * realloc(void * ptr,size_t size)

realloc()函數(shù)讓動態(tài)內(nèi)存管理更加靈活 .在程序運行過程中動態(tài)分配內(nèi)存大小,  如果分配的太大 ,則浪費空間, 如果太小, 可能還是會出現(xiàn)不夠用的情況 .為了合理的利用內(nèi)存,我們一定會對內(nèi)存的大小做靈活的調(diào)整。那realloc() 函數(shù)就可以做到對動態(tài)開辟內(nèi)存大小的調(diào)整(既可以往大調(diào)整, 也可以往小了調(diào)整) .

1).ptr為需要調(diào)整的內(nèi)存地址
2).size為調(diào)整后需要的大小(字節(jié)數(shù))
3).若調(diào)整成功, 返回值為調(diào)整大小后內(nèi)存的起始位置(也就是指向調(diào)整后內(nèi)存的指針), 若失敗(當(dāng)沒有內(nèi)存可以分配時, 一般不會出現(xiàn)), 則返回NULL, 所以還是要對返回值判空
4).如果ptr是空指針, 則和malloc()函數(shù)一樣作用一樣

注意 : realloc()函數(shù)在擴大內(nèi)存空間時有兩種情況

1).ptr所指的內(nèi)存后有足夠的內(nèi)存空間用來擴展 ,如圖 :

2).ptr所指內(nèi)存后沒有足夠的空間來擴展 ,如圖 : 

當(dāng)?shù)诙N情況時, 若申請新的內(nèi)存空間成功, 會將ptr所指向的內(nèi)存中的內(nèi)容拷貝到新的內(nèi)存空間中, ptr所指向的內(nèi)存會被釋放, 返回新得內(nèi)存地址, 若不成功 ,ptr 所指內(nèi)存不會被釋放, 函數(shù)返回NULL

5.小結(jié)

1).malloc()和calloc()函數(shù)用法一樣, 唯一的區(qū)別是calloc()會對所申請內(nèi)存的每個字節(jié)初始化為0

2).malloc(), calloc(), realloc()申請的內(nèi)存不再使用時 ,一定要用free()釋放 ,否則會造成內(nèi)存泄漏

3).p = realloc(ptr, size)函數(shù)返回值不為空時, 釋放內(nèi)存時不需寫free(ptr) ,只需寫free(p) 

到此這篇關(guān)于C語言動態(tài)內(nèi)存分配函數(shù)的實現(xiàn)的文章就介紹到這了,更多相關(guān)C語言動態(tài)內(nèi)存分配函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言中浮點數(shù)的精度丟失問題解決

    C語言中浮點數(shù)的精度丟失問題解決

    大家好,本篇文章主要講的是C語言中浮點數(shù)的精度丟失問題解決,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • C語言中各種運算類型全面總結(jié)

    C語言中各種運算類型全面總結(jié)

    C語言運算符是說明特定操作的符號,它是構(gòu)造C語言表達式的工具,C語言的運算異常豐富,除了控制語句和輸入輸出以外的幾乎所有的基本操作都為運算符處理
    2022-04-04
  • C++中的for-each循環(huán)使用

    C++中的for-each循環(huán)使用

    范圍循環(huán)是C++11引入的特性,用于簡化數(shù)組和容器的遍歷過程,它通過直接操作元素而不是使用索引或迭代器,范圍循環(huán)可以使用引用或const修飾符來控制元素的修改權(quán)限,適用于所有支持begin()和end()方法的容器,該循環(huán)方式不適用于未提供這些方法的C++98/03容器
    2024-09-09
  • C++中結(jié)構(gòu)體和Json字符串互轉(zhuǎn)的問題詳解

    C++中結(jié)構(gòu)體和Json字符串互轉(zhuǎn)的問題詳解

    這篇文章主要給大家介紹了關(guān)于C++中結(jié)構(gòu)體和Json字符串互轉(zhuǎn)問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C語言開源庫iniparser解析ini文件的方法

    C語言開源庫iniparser解析ini文件的方法

    INI(Initialization?File)文件是一種簡單直觀的數(shù)據(jù)存儲格式,常用于配置應(yīng)用程序的初始化設(shè)置,使用?iniparser?庫的應(yīng)用程序可以很方便地讀取和解析INI文件中的配置信息,大大簡化了對配置文件的處理工作,降低了程序的開發(fā)復(fù)雜度,感興趣的的朋友跟隨小編一起看看吧
    2024-04-04
  • C語言中數(shù)據(jù)如何存儲進內(nèi)存揭秘

    C語言中數(shù)據(jù)如何存儲進內(nèi)存揭秘

    使用編程語言進行編程時,需要用到各種變量來存儲各種信息。變量保留的是它所存儲的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個變量時,就會在內(nèi)存中保留一些空間。您可能需要存儲各種數(shù)據(jù)類型的信息,操作系統(tǒng)會根據(jù)變量的數(shù)據(jù)類型,來分配內(nèi)存和決定在保留內(nèi)存中存儲什么
    2022-08-08
  • C++ stack與queue使用方法詳細講解

    C++ stack與queue使用方法詳細講解

    stack是一種容器適配器,專門用在具有后進先出操作的上下文環(huán)境中,其刪除只能從容器的一端進行 元素的插入與提取操作;隊列是一種容器適配器,專門用于在FIFO上下文(先進先出)中操作,其中從容器一端插入元素,另一端提取元素
    2023-01-01
  • C語言基礎(chǔ)文件操作方式超全詳解建議收藏

    C語言基礎(chǔ)文件操作方式超全詳解建議收藏

    這篇文章主要為大家介紹了關(guān)于C語言文件操作方式的詳細總結(jié),建議收藏隨用隨看,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • C++string底層框架模擬實現(xiàn)代碼

    C++string底層框架模擬實現(xiàn)代碼

    本節(jié)文章主要說明淺拷貝和深拷貝的優(yōu)缺點,以及仿寫string類的邏輯并分析實現(xiàn)過程,對C++string底層框架模擬實現(xiàn)代碼感興趣的朋友一起看看吧
    2021-11-11
  • C語言楊氏矩陣中查找元素的示例代碼

    C語言楊氏矩陣中查找元素的示例代碼

    本文主要介紹了C語言楊氏矩陣中查找元素的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07

最新評論

乡城县| 永城市| 沙湾县| 成安县| 东乌| 五河县| 舞钢市| 布尔津县| 沿河| 勃利县| 买车| 博白县| 高淳县| 化州市| 连平县| 内江市| 灵台县| 盐城市| 汝城县| 安乡县| 安远县| 宾阳县| 瑞金市| 华容县| 麻城市| 南宁市| 万载县| 五家渠市| 婺源县| 泰和县| 高安市| 山阳县| 平顺县| 甘谷县| 图们市| 利津县| 吴忠市| 邓州市| 长寿区| 长兴县| 桂阳县|