malloc、calloc和realloc區別
在C語言中,記憶體分為四塊儲存區域:棧區,堆區,靜態儲存區,程式碼區。堆記憶體是一種在需要時申請,在不需要時釋放的記憶體塊,都是由程式設計師來完成的。
主要探討一下動態分配堆記憶體的庫函式,這些庫函式包含在標頭檔案<stdlib.h>中。
1.malloc函式
原型為 void* malloc(size_t size);這個函式向記憶體申請一塊連續可用的空間,並返回指向這塊空間的指標。
演示示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int main()
{
/* 1. malloc返回的是void *型別,在需要時候的時候要做一個適合目標指標型別的轉換,比如這裡強制型別轉換成int *;
如果是 char *p = (char *)malloc(10);
*/
int *p = (int *)malloc(10 * sizeof(int));
//int *p = (int *)malloc((size_t)(1024*1024*1024*2)); //執行此句就會執行失敗,
//所以malloc之後一定要做一個是否申請記憶體成功的判斷
if (!p)
{
printf("malloc 失敗, p = %p\n", p);
exit(1);
}
// 2.malloc分配的記憶體它的值是隨機
printf("malloc剛申請的一段記憶體其值是:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
printf("\n");
// 賦初值
for (int i = 0; i < 10; i++)
{
*(p + i) = i;
}
printf("初始化後的資料:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
printf("\n");
printf("free前的p = %p\n", p);
free(p);
//p = NULL;
// 3. 測試free後指向的記憶體區域數值
printf("free後的p_a = %p\n", p);
printf("測試free後指向的記憶體區域數值:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
printf("\n");
/*
printf("測試free還往其指向的記憶體空間寫資料:\n");
for (int i = 0; i < 10; i++)
{
*(p + i) = i; //往free後的空間寫資料,程式出錯
}
*/
printf("程式結束\n");
return 0;
}
2.calloc函式
原型為void*calloc(size_t num,size_t size);函式的功能是為num個大小為size的元素開闢一塊空間,並且把空間的每個位元組初始化為0。
演示示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int main()
{
//int *p = (int *)malloc(10*sizeof(int));
// 1. calloc的引數和malloc有區別
int *p = (int *)calloc(10, sizeof(int));
if (!p)
{
printf("malloc 失敗, p_a = %p\n", p);
exit(1);
}
// 2. calloc申請的一段記憶體空間其值都被初始化為0
printf("calloc剛申請的一段記憶體其值是:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
printf("\n");
for (int i = 0; i < 10; i++)
{
*(p + i) = i;
}
printf("初始化後的資料:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
printf("\n");
printf("free前的p = %p\n", p);
free(p);
//p_a = NULL;
// 3. 測試free後指向的記憶體區域數值
printf("free後的p = %p\n", p);
printf("測試free後指向的記憶體區域數值:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
3.realloc函式
原型為void* realloc(void*ptr,size_t size); 給一個已經分配了地址的指標重新分配空間,引數ptr為原有的空間地址,size是重新申請的地址長度,返回值為調整之後的記憶體起始位置。
realloc在調整記憶體空間存在兩種情況:
情況1:原有空間之後有足夠大的空間
情況2:原有空間之後沒有足夠大的空間
當時情況1的時候,要擴充套件記憶體就直接在原有記憶體之後直接追加空間,原來空間的資料不發生變化。當是情況2的時候,原有空間之後沒有足夠多的空間時,擴充套件的方法是:在堆空間上另找一個合適大小的連續空間來使用,這樣函式返回的是一個新的記憶體地址。
演示示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int *)malloc(10 * sizeof(int)); //申請10*sizeof(int)位元組的空間
// 1. 給p_a指向的記憶體做初始化
for (int i = 0; i < 10; i++)
{
*(p + i) = i; // 賦值
}
printf("\n初始化p指向記憶體的數值:\n");
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
// 1. 擴充資料,從10個int變為15個int
printf("\n擴充之前p = %p\n", p);
p = (int *)realloc(p, 15 * sizeof(int));
printf("擴充之後p = %p\n", p);
printf("\n擴充之後的的數值:\n"); // 擴充後地址空間是很有可能發生變化的
for (int i = 0; i < 15; i++)
{
printf("%d ", *(p + i)); // 原有的內容的數值沒有變化, 但擴充之後的數值是不確定的
}
// 2. 縮減資料
p = (int *)realloc(p, 5 * sizeof(int));
printf("\n縮減之後p = %p\n", p);
printf("\n縮減之後的的數值:\n"); //
for (int i = 0; i < 15; i++)
{
printf("%d ", *(p + i)); // 縮減記憶體後被縮減部分的資料有變化
}
// 測試越界使用
for (int i = 0; i < 10; i++)
{
*(p + i) = i; // 賦值
}
free(p);
p = NULL; // 記憶體釋放後將p置為NULL
printf("程式結束\n");
return 0;
}
4.free函式
申請的記憶體最終需要通過函式free來釋放.void free(void*ptr);prt=NULL;
相關文章
- malloc,calloc,realloc及動態開闢記憶體常見錯誤記憶體
- new 和 malloc 的區別 及使用
- 細說new和malloc的十大區別
- 關於Fork和Malloc的思考
- realloc簡單用法
- 和區別
- ../和./和/的區別
- LinkedList和ArrayList的區別、Vector和ArrayList的區別
- http和https的區別/get和post的區別HTTP
- struct和malloc記憶體互轉例子Struct記憶體
- 在malloc和free上的一天
- ||和??的區別
- /*和/**的區別
- CSAPP Malloc LabAPP
- Synchronize和ReentrantLock區別ReentrantLock
- SSL和TLS 區別TLS
- jquery $(this) 和this的區別jQuery
- ClassNotFoundException和NoClassDefFoundError區別ExceptionError
- substr()和substring()區別
- JQuery this和$(this)的區別jQuery
- insert和insertSelective區別
- SCSS 和 SASS 區別CSS
- T和?的區別
- localStorage和sessionStorage區別Session
- BeanFactory和FactoryBean區別Bean
- Swift和Kotlin區別SwiftKotlin
- makefile =和:=的區別
- undefined 和 null 區別?UndefinedNull
- ibtis # 和 ¥ 區別
- Python之“==”和“is”區別Python
- null和undefined區別NullUndefined
- ++a和a++的區別
- stringbuilder和stringbuffer區別UI
- SpringCloud和Dubbo區別SpringGCCloud
- sleep()和wait()區別AI
- JoinPoint和ProceedingJoinPoint區別
- 127.0.0.0和localhost區別localhost
- ./ 和sh 的區別