九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
動態(tài)內(nèi)存分配

動態(tài)內(nèi)存分配

分類: Linux-C C的往事 192人閱讀 評論(0) 收藏 舉報

前言

1.數(shù)組的元素存儲于內(nèi)存中連續(xù)的位置上。當(dāng)一個數(shù)組被聲明時,它所需要的內(nèi)存在編譯時就被分配。

2.但是我們也可以使用動態(tài)內(nèi)存分配在運(yùn)行時為它分配內(nèi)存。

3.為什么使用動態(tài)內(nèi)存分配

1>當(dāng)使用數(shù)組時,必須用一個常量來指定數(shù)組的長度。但是,有時候,數(shù)組的長度常常在運(yùn)行時才知道。因此,在某些情況下,我們通常采取聲明一個較大的數(shù)組,它可以容納可能出現(xiàn)的最多元素。

2>該方法的優(yōu)點是:簡單。

3>它的缺點是:

  這種聲明在程序中引入了人為的限制,如果程序需要使用的元素數(shù)量超過了聲明的長度,它就無法處理這種情況。要避免這種情況,最簡單的方法就是把數(shù)組聲明的更大一些。

  如果程序?qū)嶋H需要的元素數(shù)量比較少時,巨型數(shù)組的絕大部分內(nèi)存空間都被浪費(fèi)了。

  如果輸入的數(shù)據(jù)超過了數(shù)組的容納范圍時,程序必須以一種合理的方式作出響應(yīng)。

一.malloc和free

1.c函數(shù)庫提供了兩個函數(shù),malloc和free,分別用于執(zhí)行動態(tài)內(nèi)存分配和釋放。這些函數(shù)維護(hù)一個可用內(nèi)存。

2.當(dāng)一個程序另外需要一些內(nèi)存時,它就調(diào)用malloc函數(shù),malloc從內(nèi)存池中提取一塊合適的內(nèi)存。并向該程序返回一個指向這塊內(nèi)存的指針。這塊內(nèi)存此時并沒有以任何方式進(jìn)行初始化。如果要對其進(jìn)行初始化,要么自己動手進(jìn)行初始化,要么使用calloc()函數(shù)。當(dāng)一塊以前分配的內(nèi)存不在使用時,程序調(diào)用free函數(shù)把它歸還給內(nèi)存池供以后使用。

3.這兩個函數(shù)的原型如下,都在頭文件stdlib.h中聲明

1>void *malloc(size_t  size);

2>void   free(void  *pointer)

4.malloc的參數(shù)就是需要分配的內(nèi)存字節(jié)數(shù)。如果內(nèi)存池中的可用內(nèi)存可以滿足這個需求,malloc就返回一個指向被分配的內(nèi)存塊起始位置的指針。

1>malloc所分配的是一塊連續(xù)的內(nèi)存。例如:如果請求分配100個字節(jié)的內(nèi)存,那么它實際分配的內(nèi)存就是100個連續(xù)的字節(jié),并不會分開位于兩塊或多塊不同的內(nèi)存。同時,malloc實際分配的內(nèi)存有可能比你請求的稍微多一點。但是這時由編譯器定義的。

2>如果內(nèi)存池是空的,或者它的可用內(nèi)存無法滿足要求時。在該情況下,malloc()函數(shù)向操作系統(tǒng)請求,要求得到更多地內(nèi)存,并在這塊內(nèi)存上執(zhí)行分配任務(wù)。如果操作系統(tǒng)無法向malloc提供更多的內(nèi)存,malloc就返回一個NULL指針。因此,要對每個從malloc返回的指針都進(jìn)行檢查,確保它并非NULL是非常重要的。

5.free的參數(shù)必須要么是NULL,要么是一個先前從malloc,calloc或realloc返回的數(shù)值。想free傳遞一個NULL參數(shù)不會產(chǎn)生任何效果。

6.malloc并不知道請求的內(nèi)存需要存儲的是整型、浮點值、結(jié)構(gòu)還是數(shù)組。Malloc返回一個類型為void *的指針。在標(biāo)準(zhǔn)中表示一個void *類型的指針可以轉(zhuǎn)換為其他任何類型的指針。因此,在使用前,要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。

二.calloc和realloc

1.還有兩個內(nèi)存分配函數(shù),calloc和realloc。它們的原型如下:

void   *calloc(size_t num_elements,size_t element_size);

void   realloc(void  *ptr,size_t  new_size);

2.calloc也用于分配內(nèi)存。malloc和calloc之間的區(qū)別是后者在返回指向內(nèi)存的指針之前把它初始化為0。但如果程序只是想把一些值存儲到數(shù)組中,那么這個初始化過程純屬浪費(fèi)時間。

3.calloc和malloc之間另一個較小的區(qū)別是它們請求內(nèi)存數(shù)量的方式不同。calloc的參數(shù)包括所需元素的數(shù)量和每個元素的字節(jié)數(shù)。根據(jù)這些值,它能夠計算出總共需要分配的內(nèi)存。

4.realloc函數(shù)用于修改一個原先已經(jīng)分配的內(nèi)存塊大小。

1>使用這個函數(shù),你可以使一塊內(nèi)存擴(kuò)大或縮小。如果它用于擴(kuò)大一個內(nèi)存塊,那么這塊內(nèi)存原先的內(nèi)容依然保留,新增加的內(nèi)存添加到原先內(nèi)存塊的后面,新內(nèi)存并未以任何方法進(jìn)行初始化。

2>如果它用于縮小一塊內(nèi)存塊,該內(nèi)存塊尾部的部分內(nèi)存便被拿掉,剩余部分內(nèi)存的原先內(nèi)容依然保留。

3>如果原先的內(nèi)存塊無法改變大小,realloc將分配另一塊正確大小的內(nèi)存,并把原先那塊內(nèi)存的內(nèi)容復(fù)制到新的塊上。因此,在使用realloc之后,就不能再使用指向舊內(nèi)存的指針,而是應(yīng)該該用realloc所返回的新指針。

4>如果realloc函數(shù)的第一個參數(shù)是NULL,那么它的行為就和malloc一模一樣。

三.使用動態(tài)內(nèi)存分配實例

1.使用malloc分配一塊內(nèi)存

int  *pi;

….

pi = malloc(100);

if (pi  ==  NULL){

           printf(“Outof  memory!\n”);

           exit(1);

}

符號NULL定義于stdio.h,它實際上是字符值常量0。

1>如果內(nèi)存分配成功,那么得到了一個指向100個字節(jié)的指針。在整型為4個字節(jié)的機(jī)器上,這塊內(nèi)存將被當(dāng)作25個整型元素的數(shù)組,因為pi是一個指向整型的指針。

2>但是,使用上面的程序可移植性較差:

可以使用如下的方法:

pi  =  malloc(25 *sizeof(int));

使用該方法,即使在整數(shù)長度不同的機(jī)器上,它也能獲得正確的結(jié)果。

3>已經(jīng)有了指針,,如何使用這塊內(nèi)存呢。可以使用間接訪問和指針運(yùn)算來訪問數(shù)組的不同整數(shù)位置,下面通過循環(huán)來給新分配的數(shù)組的每個元素都初始化為0.

int  *pi2,i;

……

pi2 =  pi;

for(i = 0;i <25;i++)

*pi2++=0;

我們也可以使用小標(biāo)來運(yùn)算。

  int  i;

  …..

  for( I=0;i<25;i++)

pi[i] = 0;

四.常見的動態(tài)內(nèi)存錯誤

1.使用動態(tài)內(nèi)存分配的程序中,常常會出現(xiàn)很多錯誤。

1>對NULL指針進(jìn)行解引用操作

2>對分配的內(nèi)存進(jìn)行操作時越過邊界

3>釋放并非動態(tài)分配的內(nèi)存

4>試圖釋放一塊動態(tài)分配的內(nèi)存的一部分以及一塊內(nèi)存被釋放之后被繼續(xù)使用。

說明:

2 動態(tài)分配最常見的錯誤就是忘記檢查所請求的內(nèi)存是否成功分配。

2 2.動態(tài)內(nèi)存分配的第二大錯誤來源是操作內(nèi)存時超出了分配內(nèi)存的邊界。

2.當(dāng)你使用free時,可能出現(xiàn)各種不同的錯誤。

1>傳遞給free的指針必須是一個從malloc、calloc或realloc函數(shù)返回的指針。

2>傳遞給free函數(shù)一個指針,讓它釋放一塊并非動態(tài)分配的內(nèi)存可能導(dǎo)致程序立即終止或在晚些時候終止。

3>試圖釋放一塊動態(tài)分配內(nèi)存的一部分也有可能引起類似問題。

Eg:

/**

***Get 10 integers

**/

 pi  = malloc(10*sizeof(int ));

 ….

 /*

**僅釋放后5個整數(shù),前面的5個數(shù)不釋放

*/

free(pi + 5);

說明:

2 釋放一塊內(nèi)存的一部分是不允許的。動態(tài)分配的內(nèi)存必須整塊一起釋放。但是,realloc函數(shù)可以縮小一塊動態(tài)分配的內(nèi)存,有效地釋放它尾部的部分內(nèi)存。

4>不要訪問已經(jīng)被free函數(shù)釋放了的內(nèi)存。假定對一個指向動態(tài)分配的內(nèi)存的指針進(jìn)行了復(fù)制,而且這個指針的幾份拷貝分散于程序各處。你無法保證當(dāng)你使用其中一個指針時它所指向的內(nèi)存是不是已被另一個指針釋放。還要確保程序中所有使用這塊內(nèi)存的地方在這塊內(nèi)存釋放之前停止對它的使用。

5>當(dāng)動態(tài)分配的內(nèi)存不再需要使用時,應(yīng)該被釋放,這樣可以被重新分配使用。分配內(nèi)存但在使用完畢后不釋放將引起內(nèi)存泄漏(memory leak)。

總結(jié):

1.當(dāng)數(shù)組被聲明時,必須在編譯時知道它的長度。動態(tài)內(nèi)存分配允許程序為一個長度在運(yùn)行時才知道的數(shù)組分配內(nèi)存空間。

2.malloc和calloc函數(shù)都用于動態(tài)分配一塊內(nèi)存,并返回一個指定該塊內(nèi)存的指針。

1>malloc的參數(shù)就是需要分配的內(nèi)存的字節(jié)數(shù)。

2>calloc的參數(shù)是需要分配的元素個數(shù)和每個元素的長度。calloc函數(shù)在返回前把內(nèi)存初始化為零。malloc函數(shù)返回時內(nèi)存并未以任何方式進(jìn)行初始化。

3>調(diào)用realloc函數(shù)可以改變一塊已經(jīng)動態(tài)分配的內(nèi)存的大小。增加內(nèi)存塊大小有時有可能采取的方法是把原來內(nèi)存塊上的所有數(shù)據(jù)復(fù)制到一個新的、更大的內(nèi)存塊上。當(dāng)一個動態(tài)分配的內(nèi)存塊不再使用時,應(yīng)該調(diào)用free函數(shù)把它歸還給可用內(nèi)存池,內(nèi)存釋放后便不能再被訪問。

3.如果請求的內(nèi)存分配失敗,malloc、malloc和readlloc函數(shù)返回的將是一個NULL指針。

4.錯誤的訪問分配內(nèi)存之外的區(qū)域所引起的后果類似越界訪問一個數(shù)組,但這個錯誤還能破壞可用內(nèi)存池,導(dǎo)致程序失敗。

5.如果一個指針不是從早先的malloc、calloc或realloc函數(shù)返回的,它是不能作為參數(shù)傳遞給free函數(shù)的。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C語言的那些小秘密之動態(tài)數(shù)組
c與c++分別是怎樣動態(tài)分配和釋放內(nèi)存的,有什么區(qū)別?(轉(zhuǎn)) demo大全
3.4 動態(tài)內(nèi)存分配 (Dynamic memory)
詳解動態(tài)內(nèi)存分配函數(shù)malloc、calloc、realloc、free的區(qū)別
malloc
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服