程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> malloc,calloc,realloc,free函數

malloc,calloc,realloc,free函數

編輯:C++入門知識

在進行C/C++編程的時候,需要程序員對內存的了解比較清楚,經常需要操作的內存可分為下面幾個類別:

    1.堆棧區(stack):由編譯器自動分配與釋放,存放函數的參數值,局部變量,臨時變量等等,它們獲取的方式都是由編譯器自動執行的;    2.堆區(heap):一般由程序員分配與釋放,如果編程者不釋放,程序結束時可能由操作系統回收(注意:C/C++沒有這種回收機制,但Java/C#有)。我們這裡說的堆區與數據結構中的堆是兩回事,分配方式類似於鏈表;    3.全局區(靜態區)(static):全局變量和靜態變量的存儲是放在一塊兒的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域,程序結束後由系統釋放。    4.文字常量區:常量字符串是放在這裡的,程序結束後由系統釋放。    5.程序代碼區:存放函數體的二進制代碼。
 
    C標准函數庫提供了許多函數來實現對堆上內存管理,其中包括:malloc函數、calloc函數、realloc函數和free函數。使用這些函數需要包含頭文件stdlib.h。
它們的聲明如下:
•void* malloc(int n);
•void  free (void * p);
•void* calloc(int n,int size);

•void* realloc(void * p,int n);

 


1. malloc函數
 
malloc函數可以從堆上獲得指定字節的內存空間,其函數聲明如下:
    void* malloc(int n);
   若函數執行成功,malloc返回獲得內存空間的首地址;當函數執行失敗,就返回NULL。其中,形參n為要求分配的字節數。由於malloc函數值的類型為void型指針,所以將其值類型轉換後可以賦給任意類型指針,這樣就可以通過操作該類型指針來操作從堆上獲得的內存空間。
    通過malloc函數分配得到的內存空間是沒有被初始化的。我們可以通過使用memset函數來將其初始化為0。
    memset函數的聲明如下:
    void * memset (void * p,int c,int n) ;
    該函數可以將指定的內存空間按字節單位置為指定的字符c。其中,p為要清零的內存空間的首地址,c為要設定的值,n為被操作的內存空間的字節長度。如果要用memset清0,變量c實參要為0。malloc函數和memset函數的操作語句一般如下:
        int * p=NULL;
        p=(int *)malloc(sizeof(int));
        if(p==NULL)
           printf(“Can’t get memory!\n”);

        memset(p,0,siezeof(int));

2. calloc函數

 
calloc函數的功能與malloc函數的功能相似,都是從堆分配內存。
其函數聲明如下:
    void *calloc(int n,int size);
    函數返回值為void型指針。如果執行成功,函數從堆上獲得大小為size*n個字節空間,並返回該空間的首地址。如果執行失敗,函數返回NULL。

    該函數與malloc函數的一個顯著不同時是,calloc函數得到的內存空間是經過初始化的,其內容全為0。calloc函數適合為數組申請空間,可以將size設置為數組元素的空間長度,將n設置為數組的容量。

3. realloc函數 

用realloc函數可以實現內存分配和內存釋放的功能,其函數聲明如下:

    void * realloc(void * p,int n);

其中,指針p為指向堆內存空間的指針,即由malloc函數、calloc函數或realloc函數分配空間的指針。realloc函數將指針p指向的內存塊的大小改變為n字節。如果n小於或等於p之前指向的空間大小,那麼。保持原有狀態不變。如果n大於原來p之前指向的空間大小,系統將重新為p從堆上分配一塊大小為n的內存空間;同時,將原來指向空間的內容依次復制到新的內存空間上,p之前指向的空間被釋放。relloc函數分配的空間也是未初始化的。

4. free函數

 
    從堆上獲得的內存空間在程序結束以後,系統不會將其自動釋放,需要編程者自己來管理。一個程序結束時,必須保證所有從堆上獲得的內存空間已被安全釋放,否則,會導致內存洩露。例如上面的代碼就會發生內存洩露。
free函數可以實現釋放內存的功能。其函數聲明為:
    void free ( * p);
    free函數只是釋放指向原來指向的地方,這時的指針為野指針,如果此時操作該指針會導致不可預期的錯誤。
    所以當在使用free函數釋放指針指向的空間之後,應該將指針的值置為NULL。對於上面的代碼,需要程序結束前加入以下兩行語句:
     free(p);    
     p=NULL; 
    注意:使用malloc函數,calloc函數和realloc函數分配的內存空間都要使用free函數來釋放;free函數可以接受任意類型的指針實參。

malloc()分配的空間沒有初始化,relloc()如果沒有足夠可用的內存用來完成重新分配(擴大原來的內存塊或者分配新的內存塊),則返回null.而原來的內存塊保持不變。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved