1. 程式人生 > >malloc函式和calloc函式的區別

malloc函式和calloc函式的區別

一、記憶體分析


(1)棧(stack):由編譯器自動分配釋放,存放函式的引數值、區域性變數的值、返回地址等, 在可執行檔案a.out中不存在分配棧區的空間。

(2)堆(heap):一般有程式設計師自身呼叫(malloc,calloc函式)來分配空間, 通過free函式釋放空間, 但可能會因為程式設計師的程式設計失誤造成記憶體的洩漏,另外當程式結束的時候其動態申請的所有空間都將會由系統回收再利用。

(3)資料段(data):存放的是全域性變數、靜態變數、常數。根據存放的資料,資料段又可以分為普通資料段(包括可讀可寫/只讀資料段,存放靜態初始化的全域性變數或常量)、BSS資料段(存放未初始化的全域性變數

)。在採用段式記憶體管理的架構中,BSS段(bss segment)通常是指用來存放程式中未初始化的全域性變數的一塊記憶體區域。

(4) 文字常量區   —常量字串就是放在這裡的。   程式結束後由系統釋放 

(5)程式碼段(code):用於存放程式程式碼。這部分割槽域的大小在程式執行前就已經確定,並且記憶體區域通常屬於只讀, 某些架構也允許程式碼段為可寫,即允許修改程式。在程式碼段中,也有可能包含一些只讀的常數變數,例如字串常量等

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>

int a = 1;	//分配在靜態儲存區, (.data) 
int b ;  // .bss
const int c = 1; //常量儲存區 
 

int main()
{
	static int  a = 1; //靜態儲存區
	int b;//棧區
	int *c = new int();//堆區 
	
	return 0;
}

二、malloc函式與calloc函式

malloc函式

void* malloc(size_t n);
注意事項:

1、該函式會申請一片大小為n的連續空間, 但是這段空間並不會被初始化(如果這段空間從來被使用, 那麼每一位可能是0,那片空間都使用過, 那麼就會留下各種雜亂的資料)。

2、malloc的返回型別是void *型別, 根據C/C++規定, void *型別可以強制轉化為任何型別的指標

3、所以每次呼叫了該函式分配空間都要呼叫memset(void *, int, size_t)函式初始化

calloc函式

void *calloc(unsigned int t, size_t n);

注意事項:

1、該函式與malloc相似缺不同, 因為他要分配t*n大小的連續空間, 並且會將空間初始化0, 以保證無論該動態分配的空間是否使用過都不影響這片空間的使用。

實驗一:

驗證malloc不初始化空間:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std; 

int main()
{
	
	int *num = (int*)malloc(sizeof(int)*7);
	for(int i = 0; i < 7; ++i){
		num[i] = i + 1;
	}
	printf("num = 0x%08x\n", num);
	free(num); 
	
	
	int *p = (int*)malloc(sizeof(int)*7);
	printf("p = 0x%08x\n", p);
	for(int i = 0; i < 7; ++i){
		printf("p[%d] = %d\n", i, p[i]);
	}
	free(p); 
	return 0;
}

結果:


結果分析:

1、第一次molloc和第二次malloc分配到了相同的空間。

2、在第一次malloc後, 通過迴圈初始化資料, 第二次malloc後,列印其值, 可以看得出來, 出現了第一次初始化的值 3 4 5  6 7

3、針對為什麼會出現p[0], p[1]的值不一樣, 有待進一步討論。


實驗二, 如果把第二malloc該用calloc分配空間:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std; 

int main()
{
	
	int *num = (int*)malloc(sizeof(int)*7);
	for(int i = 0; i < 7; ++i){
		num[i] = i + 1;
	}
	printf("num = 0x%08x\n", num);
	free(num); 
	
	
	int *p = (int*)calloc(7,sizeof(int));
	printf("p = 0x%08x\n", p);
	for(int i = 0; i < 7; ++i){
		printf("p[%d] = %d\n", i, p[i]);
	}
	free(p); 
	return 0;
}
結果:


結果分析:

1、此時出現了calloc分配的空間答應其值為0, 那是因為calloc分配空間後, 對其所屬空間進行了初始化處理。


三、總結

1、malloc和calloc的區別, 以及注意事項