一、一個由C/C++編譯的程式占用的記憶體分為以下幾個部分
1、棧區(stack)—由編譯器自動配置設定釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于資料結構中的棧
2、堆區(heap)— 一般由程式員配置設定釋放,若程式員不釋放,程式結束時可能由OS回收。注意它與資料結構中的堆是兩回事,配置設定方式倒是類似于連結清單
3、全局區(靜态區)(static)—,全局變量和靜态變量的存儲是放在一塊的,初始化的全局變量和靜态變量在一塊區域,未初始化的全局變量和未初始化的靜态變量在相鄰的另一塊區域。-程式結束後有系統釋放
4、文字常量區—常量字元串就是放在這裡的。 程式結束後由系統釋放
5、程式代碼區—存放函數體的二進制代碼。
//main.cpp
inta = ; //全局初始化區
char*p1; //全局未初始化區
main()
{
int b; //棧
char s[] = "abc"; //棧
char *p2; //棧
char *p3 = "123456"; //123456\0在常量區,p3在棧上。
static int c =; //全局(靜态)初始化區
p1 = (char *)malloc();
p2 = (char*)malloc();* //配置設定得來的10和20位元組的區域就在堆區, 但是注意p1、p2本身是在棧中的
strcpy(p1,"123456"); //123456\0放在常量區,編譯器可能會将它與p3所指向的"123456"優化成一個地方。
}
二、new建立類對象與不new差別
下面是自己總結的一些關于new建立類對象特點:
1.new建立類對象需要指針接收,一處初始化,多處使用
2.new建立類對象使用完需delete銷毀
3.new建立對象直接使用堆空間,而局部不用new定義類對象則使用棧空間
4.new對象指針用途廣泛,比如作為函數傳回值、函數參數等
5.頻繁調用場合并不适合new,就像new申請和釋放記憶體一樣
char* GetString(void) {
char p[] = "hello world";
return p; //此處編譯器會提出warning
}
char* GetString(void) {
char* p = "hello world";
return p;
}
第一種p是在棧上配置設定記憶體,函數結束後将會自動釋放,p指向的記憶體區域内容不是”hello world”,而是未知的内容。
第二種是傳回靜态存儲的記憶體,這裡的”hello world”是常量字元串,位于靜态存儲區,它在程式生命期内恒定不變。無論什麼時候調用GetString,均傳回一個“隻讀”的記憶體塊。
三、delete用法
1. 删除單變量位址空間
int *a = new int;
delete a; //釋放單個int的空間
2. 删除數組空間
int *a = new int[];
delete []a; //釋放int數組空間
3.關于Vector中存放指針的問題,在進行清空的時候比較安全的一種做法是:
std::vector<ClassName *> ClassNameVec;
...push_back(new ClassName());
std::vector<ClassName *>::iterator ClassNameIt = ClassNameVec.begin();
for(;ClassNameIt != ClassNameVec.end();++ClassNameIt)
{
if(*ClassNameIt != NULL)
{
delete *ClassNameIt;
*ClassNameIt = NULL;
}
}
ClassNameVec.clear();