91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

realloc函數(shù)和free函數(shù)的實驗及注意事項

C語言編程學習基地 ? 來源:C語言編程學習基地 ? 作者:Mr_Li_ ? 2022-10-21 16:51 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

realloc函數(shù)

realloc()函數(shù)可以重用或擴展以前用malloc()、calloc()及realloc()函數(shù)自身分配的內(nèi)存。

函數(shù)原型:

extern void *realloc(void *mem_address, unsigned int newsize);
//指針名 = (數(shù)據(jù)類型*) realloc (要改變內(nèi)存大小的指針名,新的大?。?。
//新的大小一定要大于原來的大小,不然的話會導致數(shù)據(jù)丟失!
//如果newsize大小為0,那么釋放mem_address指向的內(nèi)存,并返回NULL。

先判斷當前的指針是否有足夠的連續(xù)空間,如果有,擴大mem_address指向的地址,并且將 mem_address返回,如果空間不夠,先按照 newsize 指定的大小分配空間,將原有數(shù)據(jù)從頭到尾拷貝到新分配的內(nèi)存區(qū)域,而后釋放原來 mem_address 所指內(nèi)存區(qū)域(注意:原來指針是自動釋放,不需要使用free),同時返回新分配的內(nèi)存區(qū)域的首地址。即重新分配存儲器塊的地址。

1、 realloc()函數(shù)需兩個參數(shù):一個是包含地址的指針(該地址由之前的malloc()、calloc()或realloc()函數(shù)返回),另一個是要新分配的內(nèi)存字節(jié)數(shù)。

2、 realloc()函數(shù)分配第二個參數(shù)指定的內(nèi)存量,并把第一個參數(shù)指針指向的之前分配的內(nèi)容復制到新配的內(nèi)存中,且復制的內(nèi)容長度等于新舊內(nèi)存區(qū)域中較小的那一個。即新內(nèi)存大于原內(nèi)存,則原內(nèi)存所有內(nèi)容復制到新內(nèi)存,如果新內(nèi)存小于原內(nèi)存,只復制長度等于新內(nèi)存空間的內(nèi)容。

3、realloc()函數(shù)的第一個參數(shù)若為空指針,相當于分配第二個參數(shù)指定的新內(nèi)存空間,此時等價于malloc()、calloc()或realloc()函數(shù)。

4、如果是將分配的內(nèi)存擴大,則有以下3種情況:

1) 如果當前內(nèi)存段后面有需要的內(nèi)存空間,則直接擴展這段內(nèi)存空間,realloc()將返回原指針。

2) 如果當前內(nèi)存段后面的空閑字節(jié)不夠,那么就使用堆中的第一個能夠滿足這一要求的內(nèi)存塊,將目前的數(shù)據(jù)復制到新的位置,并將原來的數(shù)據(jù)塊釋放掉,返回新的內(nèi)存塊地址位置。

3) 如果申請失敗,將返回NULL,此時,原來的指針仍然有效。

注意事項:

1、第一個參數(shù)要么是空指針,要么是指向以前分配的內(nèi)存。如果不指向以前分配的內(nèi)存或指向已釋放的內(nèi)存,結(jié)果就是不確定的。

2、 如果調(diào)用成功,不管當前內(nèi)存段后面的空閑空間是否滿足要求,都會釋放掉原來的指針,重新返回一個指針,雖然返回的指針有可能和原來的指針一樣,即不能再次釋放掉原來的指針。

返回值:如果重新分配成功則返回指向被分配內(nèi)存的指針,否則返回空指針NULL。

注意:這里原始內(nèi)存中的數(shù)據(jù)還是保持不變的。當內(nèi)存不再使用時,應使用free()等函數(shù)將內(nèi)存塊釋放

#include
#include
int main()
{
  int i;
  int *t;


  int*pn = (int*)malloc(10 * sizeof(int));//這里只是申請10個int的空間
  t = pn;


  for (i = 0; i < 10; i++) {  //賦值
    pn[i] = i;
  }


          //如果將這里的數(shù)值改大就將有可能出現(xiàn)空閑空間不足,從而申請一塊新內(nèi)存
  pn = (int*)realloc(pn, 20 * sizeof(int)); //多擴充10個int空間加上之前的就是一共20個int


  for (i = 10; i < 20; i++) {//再賦值  注意從第10個開始的
    pn[i] = i;
  }


  for (i = 0; i < 20; i++) {//輸出
    printf("%3d", pn[i]);
  }


  printf("
");
  printf("p=%p 
t=%p
", pn, t);//輸出地址




  free(pn);//釋放空間
  pn = NULL;//指針指空


  return 0;




}


如果申請空間的數(shù)值較小,原來申請的動態(tài)內(nèi)存后面還有空余內(nèi)存,系統(tǒng)將直接在原內(nèi)存空間后面擴容
并返回原動態(tài)空間基地址;如果申請空間的數(shù)值較大,原來申請的空間后面沒有足夠大的空間擴容,
系統(tǒng)將重新申請一塊新的內(nèi)存,并把原來空間的內(nèi)容拷貝過去,原來空間OS自動free;如果申請空間的數(shù)值非常大,
系統(tǒng)內(nèi)存申請失敗,返回NULL,原來的內(nèi)存不會釋放。注意:如果擴容后的內(nèi)存空間較原空間小,將會出現(xiàn)數(shù)據(jù)丟失,
如果直接realloc(p, 0);相當于free(p).

使用總結(jié):

(1)realloc失敗的時候,返回NULL

(2)realloc失敗的時候,原來的內(nèi)存不改變,不會釋放也不會移動

(3)假如原來的內(nèi)存后面還有足夠多剩余內(nèi)存的話,realloc的內(nèi)存=原來的內(nèi)存+剩余內(nèi)存,realloc還是返回原來內(nèi)存的地址; 假如原來的內(nèi)存后面沒有足夠多剩余內(nèi)存的話,realloc將申請新的內(nèi)存,然后把原來的內(nèi)存數(shù)據(jù)拷貝到新內(nèi)存里,原來的內(nèi)存將被free掉,realloc返回新內(nèi)存的地址

(4)如果size為0,效果等同于free()。這里需要注意的是只對指針本身進行釋放,例如對二維指針**a,對a調(diào)用realloc時只會釋放一維,使用時謹防內(nèi)存泄露。

(5)傳遞給realloc的指針必須是先前通過malloc(),calloc(), 或realloc()分配的

(6)傳遞給realloc的指針可以為空,等同于malloc。

malloc與free函數(shù)

malloc中文叫動態(tài)內(nèi)存分配,用于申請一塊連續(xù)的指定大小的內(nèi)存塊區(qū)域以void*類型返回分配的內(nèi)存區(qū)域地址,當無法知道內(nèi)存具體位置的時候,想要綁定真正的內(nèi)存空間,就需要用到動態(tài)的分配內(nèi)存,且分配的大小就是程序要求的大小。

函數(shù)原型:

void * malloc(size_t size);


在以前 malloc返回的是char型指針,新的ANSIC標準規(guī)定,該函數(shù)返回為void型指針,因此必要時要進行類型轉(zhuǎn)換。
它能向系統(tǒng)申請分配一個長度為num_bytes(或size)個字節(jié)的內(nèi)存塊。


其作用是在內(nèi)存的動態(tài)存儲區(qū)中分配一個長度為size的連續(xù)空間。當函數(shù)申請內(nèi)存分配成功時,
此函數(shù)的返回值是分配區(qū)域的起始地址,或者說,此函數(shù)是一個指針型函數(shù),返回的指針指向該分配域的開頭位置。
(它返回的是分配得到的內(nèi)存的首字節(jié)地址),如果無法獲得符合要求的內(nèi)存塊,malloc函數(shù)會返回空指針

size為要申請的空間大小,需要我們手動的去計算,如int *p = (int * )malloc(20*sizeof(int)),如果編譯器默認int為4字節(jié)存儲的話,那么計算結(jié)果是80 Byte,一次申請一個80 Byte的連續(xù)空間,并將空間基地址強制轉(zhuǎn)換為int類型,賦值給指針p,此時申請的內(nèi)存值是不確定的。

malloc函數(shù)的實質(zhì)體現(xiàn)在,它有一個將可用的內(nèi)存塊連接為一個長長的列表的所謂 空閑鏈表的功能。

調(diào)用malloc函數(shù)時,它沿連接表尋找一個大到足以滿足用戶請求所需要的內(nèi)存塊。然后,將該內(nèi)存塊一分為二(一塊的大小與用戶請求的大小相等,另一塊的大小就是剩下的字節(jié))。接下來,將分配給用戶的那塊內(nèi)存?zhèn)鹘o用戶,并將剩下的那塊(如果有的話)返回到連接表上。

調(diào)用free函數(shù)時,它將用戶釋放的內(nèi)存塊連接到空閑鏈上。到最后,空閑鏈會被切成很多的小內(nèi)存片段,如果這時用戶申請一個大的內(nèi)存片段,那么空閑鏈上可能沒有可以滿足用戶要求的片段了。

于是,malloc函數(shù)請求延時,并開始在空閑鏈上翻箱倒柜地檢查各內(nèi)存片段,對它們進行整理,將相鄰的小空閑塊合并成較大的內(nèi)存塊。如果無法獲得符合要求的內(nèi)存塊,malloc函數(shù)會返回NULL指針(空指針),因此在調(diào)用malloc動態(tài)申請內(nèi)存塊時,一定要進行返回值的判斷。

#include
#include  


int main(void)
{
  int count, *array; /*count是一個計數(shù)器,array是一個整型指針,也可以理解為指向一個整型數(shù)組的首地址*/


  if ((array=(int *) malloc(10 * sizeof(int))) == NULL)//把類型強制轉(zhuǎn)換為int 申請內(nèi)存空間 10個int的空間 
                   //一個int大小是sizeof(int)
  {
    printf("不能成功分配存儲空間。");
    exit(1); //強制結(jié)束程序
  }


  for (count = 0; count < 10; count++) { /*給數(shù)組賦值*/
    array[count] = count;
  }


  for (count = 0; count < 10; count++) { /*打印數(shù)組元素*/
    printf("%2d", array[count]);
  }
  return 0;


}

free函數(shù):

free()是C語言中釋放內(nèi)存空間的函數(shù),通常與申請內(nèi)存空間的函數(shù)malloc()結(jié)合使用,可以釋放由 malloc()、calloc()、realloc() 等函數(shù)申請的內(nèi)存空間。

函數(shù)原型:

void free(void *ptr);
ptr-- 指針指向一個要釋放內(nèi)存的內(nèi)存塊,該內(nèi)存塊之前是通過調(diào)用 
malloc、calloc 或 realloc 進行分配內(nèi)存的。如果傳遞的參數(shù)是一個空指針,則不會執(zhí)行任何動作。
該函數(shù)不返回任何值。

上面的例子:

#include
#include  


int main(void)
{
  int count, *array; /*count是一個計數(shù)器,array是一個整型指針,也可以理解為指向一個整型數(shù)組的首地址*/


  if ((array=(int *) malloc(10 * sizeof(int))) == NULL)//把類型強制轉(zhuǎn)換為int 申請內(nèi)存空間 10個int的空間 
                              //一個int大小是sizeof(int)
  {
    printf("不能成功分配存儲空間。");
    exit(1); //強制結(jié)束程序
  }


  for (count = 0; count < 10; count++) { /*給數(shù)組賦值*/
    array[count] = count;
  }


  for (count = 0; count < 10; count++) { /*打印數(shù)組元素*/
    printf("%2d", array[count]);
  }
  
  free(array);  //剛剛沒有進行釋放內(nèi)存


  return 0;


}


******free的重要性:*******


靜態(tài)內(nèi)存的數(shù)量在編譯時是固定的,在運行期間也不會改變,
自動變量使用的內(nèi)存數(shù)量在程序執(zhí)行期間自動增加或減少,但是動態(tài)內(nèi)存分配內(nèi)存的數(shù)量只會增加,除非使用free函數(shù)進行釋放


它創(chuàng)建了指針array,并調(diào)用了malloc函數(shù)進行內(nèi)存分配了(10* 4(int) )40個字節(jié)的內(nèi)存,假設(shè),如代碼注釋所示,
遺漏了free,當函數(shù)結(jié)束時,作為自動變量的指針array也會消失,但是它所指向的40個字節(jié)的內(nèi)存卻仍然存在,
由于array指針已被銷毀,所以無法訪問這塊內(nèi)存,它也不能被重復使用,因為代碼中沒有調(diào)用free函數(shù)釋放這塊內(nèi)存,
如果是一個函數(shù),當?shù)诙握{(diào)用它時,它又創(chuàng)建了array指針,并調(diào)用malloc分配40個字節(jié)的內(nèi)存,第一次調(diào)用的40個字節(jié)的內(nèi)存已不可用,
所以malloc函數(shù)分配了另外的內(nèi)存,當函數(shù)結(jié)束時該內(nèi)存也無法被訪問和再使用,如果循環(huán)要進行1000次,那么每一次的調(diào)用都會分配內(nèi)存,
持續(xù)增加,實際上,等不到程序結(jié)束,內(nèi)存早已被耗盡,這類問題被稱為內(nèi)存泄漏,所以 為防止這類問題的發(fā)生,
必須要在動態(tài)內(nèi)存分配函數(shù)后加上free函數(shù)釋放內(nèi)存。

總結(jié):

malloc 必須要由我們計算字節(jié)數(shù),并且在返回后強行轉(zhuǎn)換為實際類型的指針。另外有一點不能直接看出的區(qū)別是,malloc 只管分配內(nèi)存,并不能對所得的內(nèi)存進行初始化,所以得到的一片新內(nèi)存中,其值將是隨機的

一般使用后要使用free(起始地址的指針) 對內(nèi)存進行釋放,不然內(nèi)存申請過多會導致內(nèi)存泄漏會影響計算機的性能,以至于得重啟電腦。如果使用過后不清零,還可以使用該指針對該塊內(nèi)存進行訪問。

通常,malloc函數(shù)要和free函數(shù)一起配對使用,free函數(shù)的參數(shù)是之前mallloc函數(shù)返回的地址(指針),該函數(shù)釋放之前malloc函數(shù)分配的內(nèi)存,因此,動態(tài)內(nèi)存分配的存儲期是從動態(tài)內(nèi)存分配函數(shù)malloc(或其他)到f調(diào)用ree函數(shù)釋放內(nèi)存為止,涉嫌malloc和free函數(shù)管理著一個內(nèi)存池。

每次調(diào)用malloc分配內(nèi)存給程序使用,每次調(diào)用free函數(shù)把內(nèi)存空間歸還給內(nèi)存池中,這樣便可以重復使用這些內(nèi)存,free函數(shù)的參數(shù)應該是一個指針,指向由malloc函數(shù)分配的一塊內(nèi)存,不能用free函數(shù)釋放通過其他方式(如 :聲明一個數(shù)組),分配的內(nèi)存,malloc函數(shù)和free函數(shù)的原型都在stdio.h頭文件中。

審核編輯:郭婷


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 存儲器
    +關(guān)注

    關(guān)注

    39

    文章

    7739

    瀏覽量

    171681
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4417

    瀏覽量

    67521

原文標題:【零基礎(chǔ)學C語言】內(nèi)存知識總結(jié):realloc函數(shù)和free函數(shù)

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    請問CW32F030的硬件注意事項有哪些?

    CW32F030的硬件注意事項有哪些
    發(fā)表于 12-25 08:20

    請問IAP功能升級流程中有哪些注意事項?

    IAP 功能升級流程中有哪些注意事項?
    發(fā)表于 12-23 07:55

    BNC轉(zhuǎn)接頭接線注意事項

    本文從工程角度總結(jié)BNC轉(zhuǎn)接頭接線過程中的關(guān)鍵注意事項,涵蓋阻抗匹配、接線規(guī)范、工藝選擇及檢測要點,幫助用戶避免常見接線問題。
    的頭像 發(fā)表于 12-19 14:04 ?404次閱讀
    BNC轉(zhuǎn)接頭接線<b class='flag-5'>注意事項</b>

    迅為RK3588開發(fā)板Android系統(tǒng)燒寫及注意事項

    迅為RK3588開發(fā)板Android系統(tǒng)燒寫及注意事項
    的頭像 發(fā)表于 12-03 15:17 ?7176次閱讀
    迅為RK3588開發(fā)板Android系統(tǒng)燒寫及<b class='flag-5'>注意事項</b>

    驅(qū)動板PCB布線的注意事項

    PCB Layout 注意事項 1)布局注意事項: ●● 整體布局遵循功率回路與小信號控制回路分開布局原則,功率部分和控制部分的 GND 分開回流到輸入 GND。 ●● 芯片的放置方向優(yōu)先考慮驅(qū)動
    發(fā)表于 12-02 07:40

    CW32F030在使用中的注意事項有哪些?

    CW32F030在使用中的注意事項有哪些?
    發(fā)表于 11-18 06:20

    emWin AppWizard 開發(fā)注意事項有哪些?

    emWin AppWizard 開發(fā)注意事項
    發(fā)表于 09-04 06:18

    別讓這些細節(jié)毀了PCBA!焊接注意事項清單

    一站式PCBA加工廠家今天為大家講講PCBA加工中電子元器件焊接注意事項有哪些?PCBA加工中電子元器件焊接注意事項。 電子元器件焊接關(guān)鍵注意事項 在PCBA加工中,焊接工藝直接影響電路板的可靠性
    的頭像 發(fā)表于 07-23 09:26 ?1205次閱讀

    美國Odyssey奧德賽電池充電注意事項全解析

    Odyssey奧德賽電池充電注意事項全解析 奧德賽電池作為高性能的深循環(huán)鉛酸電池,廣泛應用于汽車啟動、摩托車、船舶以及備用電源系統(tǒng)中。正確的充電方法不僅能夠延長電池壽命,還能保障其性能穩(wěn)定發(fā)揮
    的頭像 發(fā)表于 05-19 16:31 ?1099次閱讀
    美國Odyssey奧德賽電池充電<b class='flag-5'>注意事項</b>全解析

    IGBT器件的防靜電注意事項

    IGBT作為功率半導體器件,對靜電極為敏感。我將從其靜電敏感性原理入手,詳細闡述使用過程中防靜電的具體注意事項與防護措施,確保其安全穩(wěn)定運行。
    的頭像 發(fā)表于 05-15 14:55 ?1831次閱讀

    手機喇叭氣密性檢測儀的注意事項

    使用手機喇叭氣密性檢測儀的注意事項包括以下幾點:一、使用前注意事項仔細閱讀手機喇叭氣密性檢測儀的使用說明書,了解設(shè)備的操作方法和注意事項。檢查氣密性檢測儀的各部件是否完好,包括壓力表、傳感器、連接
    的頭像 發(fā)表于 05-15 13:38 ?751次閱讀
    手機喇叭氣密性檢測儀的<b class='flag-5'>注意事項</b>

    設(shè)置射頻網(wǎng)絡(luò)分析儀的測試條件有哪些注意事項

    ,避免接觸不良導致VSWR惡化。 三、環(huán)境干擾與測試條件1. 電磁兼容性(EMC) 注意事項: 開放實驗室測試時,環(huán)境噪聲可能淹沒微弱信號(如噪聲系數(shù)測試需噪聲<-110dBm
    發(fā)表于 05-06 16:02

    錐齒輪減速機的使用安裝和維護維修注意事項

    錐齒輪減速機的使用、安裝和維護維修注意事項涵蓋了多個方面,以下是對這些注意事項的詳細歸納: 一、使用注意事項 1. 確認規(guī)格與設(shè)計相符:在使用減速機前,請先行確認購買的規(guī)格與設(shè)計規(guī)格是否相符。 2.
    的頭像 發(fā)表于 04-21 18:13 ?1278次閱讀
    錐齒輪減速機的使用安裝和維護維修<b class='flag-5'>注意事項</b>

    掃描電鏡的日常維護有哪些注意事項?

    掃描電鏡日常維護的注意事項。
    的頭像 發(fā)表于 03-24 11:38 ?1178次閱讀
    掃描電鏡的日常維護有哪些<b class='flag-5'>注意事項</b>?

    依托raksmart服務器在多種系統(tǒng)上本地部署deepseek注意事項

    在RAKsmart服務器上本地部署DeepSeek時,需根據(jù)不同的操作系統(tǒng)和環(huán)境做好全面適配。以下是關(guān)鍵注意事項及分步指南,主機推薦小編為您整理發(fā)布依托raksmart服務器在多種系統(tǒng)上本地部署deepseek注意事項。
    的頭像 發(fā)表于 03-19 11:25 ?900次閱讀