程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> C語言 內存管理精講(malloc,calloc,free,relloc使用)

C語言 內存管理精講(malloc,calloc,free,relloc使用)

編輯:關於C

內存管理


自定義類型
簡單的用一個新的類型名代替原有的類型名


typedef int Integer;
int i,j;
Integer k;


//聲明結構體
typedef struct{


   int month;
   int day;
   int year;
}Date;                   //用typedef 生命的結構體,原結構體變量變成了一個新的類型了


Date birthday;    
Date *p;


//定義數組
typedef int Num[100];
Num a;


//定義指針
typedef char *String
String p,s[10];


//定義返回值為int類型無參數的函數指針
typedef int (*pointer)();
pointer p1,p2;


###
typedef 只是對已經存在的類型制定一個新的類型名,而沒有創造新的類型
用typedef聲明數組類型 指針類型 結構體類型 共用體類型 枚舉類型等
typedef 與 #define 表面上有相似之處
當不同的源文件中用到同一類型的數據時,常用typedef聲明一些數據類型,可以吧所有的typedef名稱聲明單獨放在一個頭文件中
使用typedef名稱有利於程序的通用與移植,有時程序會依賴與硬件的特性,用typedef類型便於移植。


------------------------------------------------------------------------


使用位域定義與結構體相仿
格式:
struct 位域結構名{
  
       類型說明   位域名:位域長度;


}


位域長度不能超過該類型的位數
可以將該類型所占的其他位忽略
可以無位域名,表示填充或者調整位置


例如:
struct sta{


    unsigned int  a:4; //占用半個字節 4位
    unsigned int :0;    //空域 第一個字節的剩余位全清零
    unsigned int b:4;   //占用半個字節 4位
    unsigned int c:4;   //占用半個字節 4位


}
>>>>>


|   a       |    空   |
|   b       |     c   |

 

再例如:
struct stb{


  int a:1;    //占用1位
  int  :2;     //表示 2個位 不用
  int b:3;    //占用3位
  int c:2;    //占用2位


}


|   a 1   |   空 2   |   b 3  |   c  2 |      //共占8個位


------------------------------------------------------------------


動態內存管理
非靜態的局部變量是分配在內存中的動態存儲區,這個存儲區是一個稱為 棧  的區域


如:int a 存放在棧區


C語言 還允許建立動態分配區域,以存放一些臨時用的數據,這些數據需要隨時開辟,不需要的時候試試釋放,這些數據是臨時存放在一個特別
的自由存儲區,成為 堆 區


如:全局變量 內存管理的手動分配單元  靜態變量都是存在 堆區


關於靜態和動態
靜態內存分配是在程序執行之前進行的,因而效率比較高,但是它缺少靈活性,要求在程序執行之前,就知道所需要的內存的類型和數量
靜態對象是有名字的變量,我們直接對起進行操作,而動態的對象是沒有名字的變量,我們通過指針間接的對他進行操作
靜態對象由編譯器自動釋放處理,動態變量需要手工釋放


方法:


malloc 
calloc
free
realloc


1、malloc(大小)   分配到堆區
void * malloc(usingned int size);單位是(byte)字節數 
          其作用是在內容的動態存儲區分配一個長度位 side 空間,此函數是一個指針型函數,返回的指針是該分配區域的開頭的位置(或首地址)
 注意指針的類型位void 即不指向任何類型的數據,只提供一個地址。放什麼類型的數據,強制轉換位什麼類型。
 如果函數未能成功申請到空間(內存不足),返回空指針 NULL


如:
//分配40個字節的連續空間,讓a指向新空間的首地址
int *a =(int*)malloc(40);
//判讀是否申請成功
if(a == NULL){


}


========================
練習:申請兩個Student類型的空間


struct  Student stu;
*p = (struct *Student) malloc(sizeof(struct Strdent)*2);
//判斷
if(p==NULL){


}


另一種:使用typedef
typedef struct Student{


  …..
……
}stu;


stu *p = (stu*) malloc( sizeof(stu)*2 );
//判斷
if(p==NULL){


}
=========================


2、 calloc(數量,大小)  分配到堆區


viid * calloc(unsigned n,unsigned size);   上例改為 int a = sizeof(stu);   stu *b = (stu*) calloc(2,a);
其作用是在內存的動態存儲區中分配n個長度位 size的連續空間,這個空間一般比較大,足以保存一個數組
可以為一維數組開辟動態存儲空間,n為數組元素個數,每個元素長度位size,這就是動態數組。


calloc  ----->malloc
如:calloc(m,n)   ---->malloc(m*n);


malloc  ----->calloc
如:malloc(a)  ---->calloc(1,a);


例如:int *a = (int*)calloc(10,sizeof(int));  if(a==NULL)  40個字節,等於分配長度為 10 的一維數組

 


3、free(指針變量) 
void free(void *p);   p=NULL;
其作用是釋放指針變量p所指向的動態空間,這部分空間能重新被其他變量使用,p應是最近一次調用calloc或malloc函數時得到的函數返回值
free(p)釋放指針變量p所指向的已分配的動態空間,但是注意,當p被釋放後,p變為野指針,所以一定要加一句  p=NULL或p=0;
free函數無返回值
動態分配的空間用完後,必須要釋放。


***** 注意 *****
在使用malloc或者cmalloc申請空間時,如 int *p  = (int*)malloc(40); 
p指針不允許進行 ++p  或者 --p,這樣將導致 部分內存區域無法歸還,導致內存洩露。


4、realloc(指針,大小)
void *realloc(void *p,unsigned int size);
如果已經通過malloc函數獲取到了動態的空間,想改變大小,可以使用relloc函數重新分配
用realloc 函數講p所指向動態空間的大小改為size,p的值不變,如果重新分配不成功,返回NULL(  "p=(int*)relloc(p,20)"  這句話有問題,一旦重新分配不成功,p=NULL,將會導致p指向的原來的空間也無法找到,無法歸還,將導致內存洩露);

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