C語言中的malloc使用詳解
一、原型:extern void *malloc(unsigned int num_bytes);
頭文件:#include <malloc.h> 或 #include <alloc.h> (注意:alloc.h 與 malloc.h 的內(nèi)容是完全一致的。)
功能:分配長(zhǎng)度為num_bytes字節(jié)的內(nèi)存塊
說明:如果分配成功則返回指向被分配內(nèi)存的指針,否則返回空指針NULL。
當(dāng)內(nèi)存不再使用時(shí),應(yīng)使用free()函數(shù)將內(nèi)存塊釋放。
舉例:
#include<stdio.h>
#include<malloc.h>
int main()
{
char *p;
p=(char *)malloc(100);
if(p)
printf("Memory Allocated at: %x/n",p);
else
printf("Not Enough Memory!/n");
free(p);
return 0;
}
二、函數(shù)聲明(函數(shù)原型):
void *malloc(int size);
說明:malloc 向系統(tǒng)申請(qǐng)分配指定size個(gè)字節(jié)的內(nèi)存空間。返回類型是 void* 類型。void* 表示未確定類型的指針。C,C++規(guī)定,void* 類型可以強(qiáng)制轉(zhuǎn)換為任何其它類型的指針。這個(gè)在MSDN上可以找到相關(guān)的解釋,具體內(nèi)容如下:
malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small.
三、malloc與new的不同點(diǎn)
從函數(shù)聲明上可以看出。malloc 和 new 至少有兩個(gè)不同: new 返回指定類型的指針,并且可以自動(dòng)計(jì)算所需要大小。比如:
int *p; p = new int; //返回類型為int* 類型(整數(shù)型指針),分配大小為 sizeof(int);
或:
int* parr; parr = new int [100]; //返回類型為 int* 類型(整數(shù)型指針),分配大小為 sizeof(int) * 100;
而 malloc 則必須由我們計(jì)算要字節(jié)數(shù),并且在返回后強(qiáng)行轉(zhuǎn)換為實(shí)際類型的指針。
int* p; p = (int *) malloc (sizeof(int));
第1、malloc 函數(shù)返回的是 void * 類型,如果你寫成:p = malloc (sizeof(int)); 則程序無法通過編譯,報(bào)錯(cuò):“不能將 void* 賦值給 int * 類型變量”。所以必須通過 (int *) 來將強(qiáng)制轉(zhuǎn)換。
第2、函數(shù)的實(shí)參為 sizeof(int) ,用于指明一個(gè)整型數(shù)據(jù)需要的大小。如果你寫成:
int* p = (int *) malloc (1);
代碼也能通過編譯,但事實(shí)上只分配了1個(gè)字節(jié)大小的內(nèi)存空間,當(dāng)你往里頭存入一個(gè)整數(shù),就會(huì)有3個(gè)字節(jié)無家可歸,而直接“住進(jìn)鄰居家”!造成的結(jié)果是后面的內(nèi)存中原有數(shù)據(jù)內(nèi)容全部被清空。
malloc 也可以達(dá)到 new [] 的效果,申請(qǐng)出一段連續(xù)的內(nèi)存,方法無非是指定你所需要內(nèi)存大小。
比如想分配100個(gè)int類型的空間:
int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100個(gè)整數(shù)的內(nèi)存空間。
另外有一點(diǎn)不能直接看出的區(qū)別是,malloc 只管分配內(nèi)存,并不能對(duì)所得的內(nèi)存進(jìn)行初始化,所以得到的一片新內(nèi)存中,其值將是隨機(jī)的。
除了分配及最后釋放的方法不一樣以外,通過malloc或new得到指針,在其它操作上保持一致。
四、動(dòng)態(tài)申請(qǐng)數(shù)組
申請(qǐng)一維數(shù)組
一維數(shù)組的數(shù)組名可以看成數(shù)組起始元素的首地址,因此我定義一個(gè)int *arr的指針,分配n個(gè)大小的int型空間,寫法如下:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n, *arr;
while (scanf("%d", &n) != EOF) {
arr = (int *)malloc(sizeof(int) * n);
}
return 0;
}
申請(qǐng)二維數(shù)組
二維數(shù)組的數(shù)組名是其所有一維數(shù)組的首地址,因?yàn)槎S數(shù)組的數(shù)組名是指針的指針,因?yàn)槲叶x一個(gè)row行column列的二維數(shù)組,寫法如下:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, row, column, **arr;
while (scanf("%d %d", &row, &column) != EOF) {
arr = (int **)malloc(sizeof(int *) * row); // 分配所有行的首地址
for (i = 0; i < row; i ++) { // 按行分配每一列
arr[i] = (int *)malloc(sizeof(int) * column);
}
free(arr);
}
return 0;
}
總結(jié):
malloc()函數(shù)其實(shí)就在內(nèi)存中找一片指定大小的空間,然后將這個(gè)空間的首地址范圍給一個(gè)指針變量,這里的指針變量可以是一個(gè)單獨(dú)的指針,也可以是一個(gè)數(shù)組的首地址,這要看malloc()函數(shù)中參數(shù)size的具體內(nèi)容。我們這里malloc分配的內(nèi)存空間在邏輯上連續(xù)的,而在物理上可以連續(xù)也可以不連續(xù)。對(duì)于我們程序員來說,我們關(guān)注的是邏輯上的連續(xù),因?yàn)椴僮飨到y(tǒng)會(huì)幫我們安排內(nèi)存分配,所以我們使用起來就可以當(dāng)做是連續(xù)的。
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(111.二叉樹的最小深度)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(111.二叉樹的最小深度),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++段錯(cuò)誤(Segmentation fault)快速定位的解決方法
寫過C++的朋友都知道,有時(shí)候程序編譯通過,并不能代表程序就是對(duì)的,在linux下做開發(fā)時(shí),經(jīng)常會(huì)遇到跑崩潰的情況,但是在終端只會(huì)報(bào)Segmentation fault,如果工程代碼量少,你還能重新debug一下慢慢找,本文給大家介紹了C++段錯(cuò)誤的快速定位,需要的朋友可以參考下2024-07-07
C語言與C++動(dòng)態(tài)通訊錄超詳細(xì)實(shí)現(xiàn)流程
這篇文章主要為大家介紹了C語言與C++動(dòng)態(tài)實(shí)現(xiàn)通訊錄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-05-05
C++使用LibCurl實(shí)現(xiàn)Web隱藏目錄掃描功能
LibCurl是一個(gè)開源的免費(fèi)的多協(xié)議數(shù)據(jù)傳輸開源庫(kù),該框架具備跨平臺(tái)性,開源免費(fèi),并提供了包括HTTP、FTP、SMTP、POP3等協(xié)議的功能,本文將給大家介紹C++使用LibCurl實(shí)現(xiàn)Web隱藏目錄掃描功能2023-11-11
QT如何通過鼠標(biāo)事件實(shí)現(xiàn)圖片的拖動(dòng)和縮放
本文介紹了如何通過鼠標(biāo)拖動(dòng)移動(dòng)圖片以及使用鼠標(biāo)滾輪進(jìn)行圖片縮放的技術(shù)實(shí)現(xiàn),包括完整的解決方案,ImageWidget.h、ImageWidget.cpp和main.cpp的編寫,以及詳細(xì)的函數(shù)解釋,如paintEvent()重繪圖片,以及平滑縮放和偏移量的應(yīng)用等,需要的朋友可以參考下2024-10-10

