c語言 malloc函數詳解

發布時間:2019-12-03 09:52 來源:互聯網 當前欄目:網站服務器

談到malloc函數相信學過c語言的人都很熟悉,但是malloc底層到底做了什么又有多少人知道。

1、關于malloc相關的幾個函數

關于malloc我們進入Linux man一下就會得到如下結果:

這里寫圖片描述 

也可以這樣認為(window下)原型:

extern void *malloc(unsigned int num_bytes);

頭文件:

#include<malloc.h>或者#include<alloc.h>兩者的內容是完全一樣的

如果分配成功:則返回指向被分配內存空間的指針

不然返回指針NULL

同時,當內存不再使用的時候,應使用free()函數將內存塊釋放掉。

關于:void*,表示未確定類型的指針,c,c++規定void*可以強轉為任何其他類型的指針,關于void還有一種說法就是其他任何類型都可以直接賦值給它,無需進行強轉,但是反過來不可以

malloc:

malloc分配的內存大小至少為參數所指定的字節數

malloc的返回值是一個指針,指向一段可用內存的起始位置,指向一段可用內存的起始地址,多次調用malloc所分配的地址不能有重疊部分,除非某次malloc所分配的地址被釋放掉malloc應該盡快完成內存分配并返回(不能使用NP-hard的內存分配算法)實現malloc時應同時實現內存大小調整和內存釋放函數(realloc和free)

malloc和free是配對的,如果申請后不釋放就是內存泄露,如果無故釋放那就是什么也沒做,釋放只能釋放一次,如果一塊空間釋放兩次或者兩次以上會出現錯誤(但是釋放空指針例外,釋放空指針也等于什么也沒做,所以釋放多少次都是可以的。)

2、malloc和new

new返回指定類型的指針,并且可以自動計算所需要的大小。

int *p;
p = new int;//返回類型為int* ,分配的大小是sizeof(int)
p = new int[100];//返回類型是int*類型,分配的大小為sizeof(int)*100

而malloc需要我們自己計算字節數,并且返回的時候要強轉成指定類型的指針。

int *p;
p = (int *)malloc(sizeof(int));

(1)malloc的返回是void*,如果我們寫成了:p=malloc(sizeof(int));間接的說明了(將void轉化給了int*,這不合理)
(2)malloc的實參是sizeof(int),用于指明一個整型數據需要的大小,如果我們寫成p=(int*)malloc(1),那么可以看出:只是申請了一個一個字節大小的空間。
(3)malloc只管分配內存,并不能對其進行初始化,所以得到的一片新內存中,其值將是隨機的。一般意義上:我們習慣性的將其初始化為NULL,當然也可以使用memset函數。

簡單的說:

malloc函數其實就是在內存中找一片指定大小的空間,然后將這個空間的首地址給一個指針變量,這里的指針變量可以是一個單獨的指針,也可以是一個數組的首地址,這要看malloc函數中參數size的具體內容。我們這里malloc分配的內存空間在邏輯上是連續的,而在物理上可以不連續。我們作為程序員,關注的是邏輯上的連續,其他的操作系統會幫著我們處理。

下面就來看看malloc具體是怎么實現的。

首先要了解操作系統相關的知識:

虛擬內存地址和物理內存地址

為了簡單,現代操作系統在處理物理內存地址時,普遍采用虛擬內存地址技術。即在匯編程序層面,當涉及內存地址時,都是使用的虛擬內存地址。采用這種技術時,每個進程仿佛自己獨享一片2N字節的內存,其中N是機器位數。例如在64位CPU和64位操作系統下每個進程的虛擬地址空間為264Byte。

  • 1、
  • 2、
  • 3、
  • 4、
  • 5、
  • 6、
  • 7、
  • 8、
  • 9、
  • 10、
  • 11、
  • 12、
  • 13、
  • 14、
  • 15、
  • 16、
  • 17、
  • 18、
  • 19、
  • 20、
  • 21、
  • 22、
  • 23、
  • 24、
  • 25、
  • 1、
  • 2、
  • 3、
  • 4、
  • 5、
  • 6、
  • 7、
  • 8、
  • 9、
  • 10、
  • 11、
  • 12、
  • 13、
  • 14、
  • 15、
  • 16、
  • 17、
  • 18、
  • 19、
  • 20、
  • 21、
  • 22、
  • 23、
  • 24、
  • 25、