搜尋
首頁後端開發C#.Net教程malloc函數的用法

malloc函數的用法

Jun 14, 2019 am 09:55 AM
malloc函數

malloc函數的用法

malloc的全名是memory allocation,中文叫動態記憶體分配,用於申請一塊連續的指定大小的記憶體區塊區域以void*類型傳回分配的記憶體區域位址,當無法知道記憶體具體位置的時候,想要綁定真正的記憶體空間,就需要用到動態的分配記憶體。

void* 類型表示未確定類型的指標。 C,C 規定,void* 類型可以透過型別轉換強制轉換為任何其它類型的指標。

一般需和free函數配對使用。

函數定義

原型

extern void *malloc(unsigned int num_bytes);

頭檔

#include <stdlib.h>

函數宣告

void *malloc(size_t size);

備註:void*表示未確定類型的指針,void *可以指向任何類型的數據,更明確的說是指申請內存空間時還不知道用戶是用這段空間來存儲什麼類型的數據(比如是char還是int或者其他數據類型)。

傳回值

如果分配成功則傳回指向被指派記憶體的指標(此儲存區中的初始值不確定),否則傳回空指標NULL。當記憶體不再使用時,應使用free()函數將記憶體區塊釋放。函數傳回的指標一定要適當對齊,使其可以用於任何資料物件。

說明

關於該函數的原型,在先前malloc返回的是char型指針,新的ANSIC標準規定,該函數返回為void型指針,因此必要時要進行類型轉換。它能向系統申請分配一個長度為num_bytes(或size)個位元組的記憶體區塊。

一般它需和free函數配對使用。 free函數能釋放某個動態分配的位址,表示不再使用這塊動態分配的記憶體了,實作把之前動態申請的記憶體回饋到系統。

相關函數

calloc、realloc、free、_alloca。

與new的區別

本質上來說,malloc(Linux上具體實作可以參考man malloc,glibc透過brk()&mmap()實作)是libc裡面實作的一個函數,如果在source code中沒有直接或間接include過stdlib.h,那麼gcc就會報出error:'malloc' was not declared in this scope。如果產生了目標檔案(假定動態連結malloc),如果執行平台上沒有libc(Linux平台,手動指定LD_LIBRARY_PATH到一個空目錄即可),或者libc中沒有malloc函數,那麼會在執行時間(Run-time)出錯。 new則不然,是c 的關鍵字,它本身不是函數。 new不依賴頭文件,c 編譯器就可以把new編譯成目標代碼(g 4.6.3會向目標中插入_Znwm這個函數,另外,編譯器還會根據參數的類型,插入對應的構造函數) 。

在使用上,malloc 和 new 至少有兩個不同: new 返回指定類型的指針,並且可以自動計算所需要大小。例如:

int *p;
p = new int;
//返回类型为int *类型(整数型指针),分配大小为sizeof(int);

或:

int *parr;
parr = new int[100];
//返回类型为int *类型(整数型指针),分配大小为sizeof(int) * 100;

而 malloc 則必須由我們計算位元組數,並且在返回後強行轉換為實際類型的指標。 

int *p;
p = (int*)malloc(sizeof(int) * 128);
//分配128个(可根据实际需要替换该数值)整型存储单元,
//并将这128个连续的整型存储单元的首地址存储到指针变量p中
double *pd = (double*)malloc(sizeof(double) * 12);
//分配12个double型存储单元,
//并将首地址存储到指针变量pd中

第一、malloc 函數回傳的是 void * 類型。

對於C ,如果你寫成:p = malloc (sizeof(int)); 則程式無法通過編譯,報錯:「不能將 void* 賦值給 int * 類型變數」。

所以必須透過 (int *) 來強制轉換。而對於C,沒有這個要求,但為了讓C程式更方便的移植到C 中來,建議養成強制轉換的習慣。

第二、函數的實參為 sizeof(int) ,用來指明一個整型資料所需的大小。

需要注意一個特殊情況malloc(0),傳回值可能是NULL或一個有效的位址(可以安全的free,但是不能解引用)。注意malloc(-1)不是禁止的,參數為無符號類型,如果是負數可能會轉換成極大的正數,最後一般會因為沒有足夠大的記憶體區塊而傳回NULL。

在規範的程序中我們有必要按照這樣的格式去使用malloc及free:

type *p;
if(NULL == (p = (type*)malloc(sizeof(type))))
/*请使用if来判断,这是有必要的*/
{
    perror("error...");
    exit(1);
}
.../*其它代码*/
free(p);
p = NULL;/*请加上这句*/

malloc 也可以達到new [] 的效果,申請出一段連續的內存,方法無非是指定你所需要記憶體大小。

例如想分配100個int類型的空間:

int *p = (int*)malloc(sizeof(int) * 100);
//分配可以放得下100个整数的内存空间。

另外有一點不能直接看出的區別是,malloc 只管分配內存,並不能對所得的內存進行初始化,所以得到的一片新記憶體中,其值將是隨機的。

除了分配及最後釋放的方法不一樣以外,透過malloc或new得到指針,在其它操作上保持一致。

對其做一個特例補充

char *ptr;
if((ptr = (char*)malloc(0)) == NULL)
    puts("Gotanullpointer");
else
    puts("Gotavalidpointer");

此時可能會得到的是Got a valid pointer,也可能會得到Got a null pointer。

工作機制

#

malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。

Linux Libc6采用的机制是在free的时候试图整合相邻的碎片,使其合并成为一个较大的free空间。

程序示例

正常程序

typedef struct data_type{
    int age;
    char name[20];
}data;
data*bob=NULL;
bob=(data*)malloc(sizeof(data));
if(bob!=NULL)
{
    bob->age=22;
    strcpy(bob->name,"Robert"); 
    printf("%s is %d years old.\n",bob->name,bob->age);
}
else
{
    printf("mallocerror!\n");
    exit(-1);
}  
free(bob);
bob=NULL;

输出结果:Robert is 22 years old.

内存泄漏实例

#include <stdio.h>
#include <malloc.h>
#define MAX 100000000int main(void)
{
    int *a[MAX] = {NULL};
    int i;
    for(i=0;i<MAX;i++)
    {
    a[i]=(int*)malloc(MAX);
    }
    return 0;
}

注:malloc申请之后没有检测返回值。

推荐教程:C#视频教程

以上是malloc函數的用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
C#.NET:使用.NET生態系統構建應用程序C#.NET:使用.NET生態系統構建應用程序Apr 27, 2025 am 12:12 AM

如何利用.NET構建應用?使用.NET構建應用可以通過以下步驟實現:1)了解.NET基礎知識,包括C#語言和跨平台開發支持;2)學習核心概念,如.NET生態系統的組件和工作原理;3)掌握基本和高級用法,從簡單控制台應用到復雜的WebAPI和數據庫操作;4)熟悉常見錯誤與調試技巧,如配置和數據庫連接問題;5)應用性能優化與最佳實踐,如異步編程和緩存。

C#作為多功能.NET語言:應用程序和示例C#作為多功能.NET語言:應用程序和示例Apr 26, 2025 am 12:26 AM

C#在企業級應用、遊戲開發、移動應用和Web開發中均有廣泛應用。 1)在企業級應用中,C#常用於ASP.NETCore開發WebAPI。 2)在遊戲開發中,C#與Unity引擎結合,實現角色控制等功能。 3)C#支持多態性和異步編程,提高代碼靈活性和應用性能。

C#.NET用於網絡,桌面和移動開發C#.NET用於網絡,桌面和移動開發Apr 25, 2025 am 12:01 AM

C#和.NET適用於Web、桌面和移動開發。 1)在Web開發中,ASP.NETCore支持跨平台開發。 2)桌面開發使用WPF和WinForms,適用於不同需求。 3)移動開發通過Xamarin實現跨平台應用。

C#.NET生態系統:框架,庫和工具C#.NET生態系統:框架,庫和工具Apr 24, 2025 am 12:02 AM

C#.NET生態系統提供了豐富的框架和庫,幫助開發者高效構建應用。 1.ASP.NETCore用於構建高性能Web應用,2.EntityFrameworkCore用於數據庫操作。通過理解這些工具的使用和最佳實踐,開發者可以提高應用的質量和性能。

將C#.NET應用程序部署到Azure/AWS:逐步指南將C#.NET應用程序部署到Azure/AWS:逐步指南Apr 23, 2025 am 12:06 AM

如何將C#.NET應用部署到Azure或AWS?答案是使用AzureAppService和AWSElasticBeanstalk。 1.在Azure上,使用AzureAppService和AzurePipelines自動化部署。 2.在AWS上,使用AmazonElasticBeanstalk和AWSLambda實現部署和無服務器計算。

C#.NET:強大的編程語言簡介C#.NET:強大的編程語言簡介Apr 22, 2025 am 12:04 AM

C#和.NET的結合為開發者提供了強大的編程環境。 1)C#支持多態性和異步編程,2).NET提供跨平台能力和並發處理機制,這使得它們在桌面、Web和移動應用開發中廣泛應用。

.NET框架與C#:解碼術語.NET框架與C#:解碼術語Apr 21, 2025 am 12:05 AM

.NETFramework是一個軟件框架,C#是一種編程語言。 1..NETFramework提供庫和服務,支持桌面、Web和移動應用開發。 2.C#設計用於.NETFramework,支持現代編程功能。 3..NETFramework通過CLR管理代碼執行,C#代碼編譯成IL後由CLR運行。 4.使用.NETFramework可快速開發應用,C#提供如LINQ的高級功能。 5.常見錯誤包括類型轉換和異步編程死鎖,調試需用VisualStudio工具。

揭開c#.net的神秘面紗:初學者的概述揭開c#.net的神秘面紗:初學者的概述Apr 20, 2025 am 12:11 AM

C#是一種由微軟開發的現代、面向對象的編程語言,.NET是微軟提供的開發框架。 C#結合了C 的性能和Java的簡潔性,適用於構建各種應用程序。 .NET框架支持多種語言,提供垃圾回收機制,簡化內存管理。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具