在撰寫程式時,通常并不知道需要處理的資料量,或者難以評估所需處理資料量的變動程度,在這種情況下,要達到有效的資源利用——使用記憶體管理,必須在運行時動態地分配所需記憶體,并在使用完畢后盡早釋放不需要的記憶體,這就是動態記憶體管理原理,動態記憶體管理同時還具有一個優點:當程式在具有更多記憶體的系統上需要處理更多資料時,不需要重寫程式,
一、動態記憶體分配
1、malloc函式
能夠在堆中動態地分配一塊指定大小的記憶體空間,malloc中文叫 動態記憶體分配 ,用于申請一塊連續的指定大小的記憶體塊區域以void*型別回傳分配的記憶體區域地址,當無法知道記憶體具體位置的時候,想要系結真正的記憶體空間 ,就需要用到動態的分配記憶體,且分配的大小就是程式要求的大小,
函式原型:
void* malloc(unsigned int size);
回傳:回傳一個指向被分配的記憶體塊起始位置
失敗回傳NULL指標,說明沒有分配成功,

2、泛型指標
void*
相同型別的指標可以相互轉化,泛型指標就是:可以轉化成任何型別的指標
int *p = malloc(sizeof(int));
if (p != NULL)
{
printf("動態開辟記憶體成功.\n");
}
else
{
printf("失敗\n");
}
*p = 45;
char *p1=malloc(sizeof(char));
*p1 = 'A';
//是分配的一塊連續的記憶體空間

3、calloc函式
有時候,我們在程式中需要一段記憶體來處理資料,但是又不確定是要多大記憶體的情況下,比如 我們申請一個陣列 a[100] 但是事前我們并不知道會不會用得完這100個元素,比如我們只會用到10個,那么剩下的90個就會還在占用空間,就顯得很浪費空間,這時候使用calloc函式是用來在記憶體的 動態存盤 區中(堆中)分配一個連續存盤空間,
//函式原型:
void *calloc( size_t num , size_t size);
//分配的這塊空間 會被初始化為0
//num Number of elements.
size Length in bytes of each element.
//效率: malloc效率要高,calloc還要將里面初始化為0.
4、realloc函式
用于修改原先已經分配好了的記憶體空間大小,realloc()函式可以重用或擴展以前用malloc()、calloc()及realloc()函式自身分配的記憶體,
函式原型:
void *realloc( void *memblock , size_t size);
memblock Pointer to previously allocated memory block.
size New size in bytes.
//擴大:
//縮小:
5、記憶體釋放
free();
//函式原型
void free(void *memblock);
int *p=malloc(sizeof(int) * 5);
p[0] = 11;
p[1] = 22;
p[2] = 33;
p[3] = 44;
p[4] = 55;
for (int i = 0; i < 5;i++)
{
printf("%d\t",p[i]);
}
printf("\n");
//釋放這塊記憶體空間
free(p);
//p野指標 指向一塊非法的記憶體空間

6、記憶體泄漏
對于任何使用 C 語言的人,如果問他們 C 語言的最大煩惱是什么,其中許多人可能會回答說是指標和記憶體泄漏,
在計算機科學中,記憶體泄漏指由于疏忽或錯誤造成程式未能釋放已經不再使用的記憶體,記憶體泄漏并非指記憶體在物理上的消失,而是應用程式分配某段記憶體后,由于設計錯誤,導致在釋放該段記憶體之前就失去了對該段記憶體的控制,從而造成了記憶體的浪費,
在C++中出現記憶體泄露的主要原因就是程式猿在申請了記憶體后(malloc(), new),沒有及時釋放沒用的記憶體空間,甚至消滅了指標導致該區域記憶體空間根本無法釋放,
知道了出現記憶體泄露的原因就能知道如何應對記憶體泄露,即:不用了的記憶體空間記得釋放!
記憶體泄漏可能會導致嚴重的后果:
● 程式運行后,隨著時間占用了更多的記憶體,最后無記憶體可用而崩潰;
● 程式消耗了大量的記憶體,導致其他程式無法正常使用;
● 程式消耗了大量記憶體,導致消費者選用了別人的程式而不是你的;
● 經常做出記憶體泄露bug的程式猿被公司開出而貧困潦倒,
如何檢測記憶體泄露
觀察記憶體泄露是一個兩步驟的程序,首先,使用swap命令觀察還有多少可用的交換空間:
/usr/sbin/swap -s
total:17228K bytes allocated + 5396K reserved=22626K used,29548K available.
在一兩分鐘內鍵入該命令三到四次,看看可用的交換區是否在減少,還可以使用其他一些/usr/bin/*stat工具如netstat、vmstat等,如發現波段有記憶體被分配且從不釋放,一個可能的解釋就是有個行程出現了記憶體泄露,

7、記憶體操作函式
#include <string.h>
memcpy()
memmove()
memchr()
memset()
//-----------
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int arr1[10];
//memcpy(arr1,arr,sizeof(arr));
memset(arr1,0,40);
for (int i = 0; i < 10;i++)
{
printf("%d\n",arr1[i]);
}
如果你也想要自學C語言,接受全面系統的指導,這里有一個交流群推薦給你,不論是小白還是進階者,在這里都能獲得成長,群內含有,學習書籍電子書資源,素材包,還有免費教學課程哦~

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/186247.html
標籤:其他
