1. 程式人生 > >C++ Primer Plus書之--C++指標及使用new分配記憶體,使用delete釋放記憶體

C++ Primer Plus書之--C++指標及使用new分配記憶體,使用delete釋放記憶體

先來個簡單的程式初步認識一下指標 

#include "iostream"
using namespace std;

int main() {
	// 定義一個int型變數
	int num = 123;
	// 定義一個int型指標變數
	int * p_num;
	// 指標指向num的地址
	p_num = #
	
	cout << "num = " << num << endl;
	cout << "*p_num = " << *p_num << endl;
	cout << "address of num is : " << &num << endl;
	cout << "p_num = " << p_num << endl;
	
	// 對p_num指向的地址裡的數+1
	// 那麼num的值也+1, 因為p_num指向的就是num的記憶體地址
	*p_num = *p_num + 1;
	cout << "num = " << num << endl;
	cout << "*p_num = " << *p_num << endl;
}

看執行結果:

 

注意使用指標的時候有個一定要注意的地方:一定要在對指標指向的記憶體進行賦值之前, 對指標的地址進行初始化, 否則我們就不知道所賦的值儲存的具體位置是哪裡, 因為指標沒有被初始化, 所以指標指向的對我們來說是未知的地址, 而我們儲存的資料也將是在那塊未知的地址裡.  舉個例子:

long* p_longNum;
*p_longNum = 12345;

上面兩行程式碼, 第一行聲明瞭一個long型指標, 第二行把12345賦值給p_longNum所指向的地址, 但是問題是我們沒有給p_longNum初始化地址, 所以我們不知道p_longNum指向了哪個地址, 也就是我們只初始化了指標變數, 而沒有對其初始化, 那麼p_longNum的值是記憶體當中原來已存在的數值, 這樣會有一些隱患

c++裡宣告指標可以是一下幾種方式:

	int*  p_num1;
	int * p_num2;
	int *p_num3;
	int*p_num4;

int * p_num ,  中間的空格可有可無 

指標和數字

注意指標不是整型, 雖然計算機通常把地址當作整數來處理. 整數可以加減乘除等運算, 而指標描述的是位置, 因此將兩個地址相乘沒有任何意義.

int* pt;
pt = 0xB1000000;

看這個例子:雖然pt是一個int型指標, 可以給pt賦一個地址, 但是這條語句並沒有告訴程式, 這個數字就是一個地址, 因此這樣賦值編譯機會報錯:

所以如果我們想把一個整型地址複製給指標可以通過強制型別轉換, 將數字轉換為合適的地址型別例如:

int* pt;
pt = (int *)0xB1000000;

 這樣等號兩邊都是整數地址, 就可以有效賦值, 注意雖然pt是int型指標, 但是不代表pt本身的型別是int, 例如有些系統int佔兩個位元組, 而指標佔4個位元組

 

C++中使用new來分配記憶體

c++中我們可以使用new來進行記憶體的分配  格式如下:

typeName * pinter_name = new typeName;

來看一個簡單的例子:

#include "iostream"
using namespace std;

int main() {
	int num = 1000;
	// 宣告一個int型指標
	int* pt = new int;
	// 給pt指標指向的記憶體裡賦1000
	*pt = 1000;
	
	cout << "num is : ";
	cout << num << " and num's location is : " << &num << endl;
	cout << "int value is : " << *pt << " and it's location  is " << pt << endl;;
	
	// 宣告一個double型別的指標變數, 並分配了記憶體空間
	double * pd = new double;
	// 給pd指標指向的記憶體裡賦1000
	*pd = 10000001.0;
	cout << "double value is : " << *pd << " and it's location is : " << pd << endl;
	cout << "location of pointer pd : " << &pd << endl;
	cout << "size of pt = " << sizeof(pt) << endl;
	cout << "size of pd = " << sizeof(pd) << endl;
	cout << "size of *pt = " << sizeof(*pt) << endl;
	cout << "size of *pd = " << sizeof(*pd) << endl;
	return 0;
}

執行結果如下:

使用delete釋放記憶體

當需要記憶體時,可以使用new來分配記憶體,當使用完記憶體後可以使用delete來釋放new分配的記憶體,例如:

// 使用new給指標pn分配記憶體
int * pn = new int;
// 使用delete來釋放pn指標指向的記憶體
delete pn;

注意:釋放pn指向的記憶體,不會刪除指標pn本身,也就是我們可以將pn重新指向另一個新分配的記憶體塊. 一定要配對的使用new和delete,否則將會發生記憶體洩漏(memory leak), 也就是說被分配的記憶體再也無法使用了, 如果記憶體洩漏嚴重, 程式將因為分配不到新記憶體而終止.

另外不要嘗試釋放已經釋放的記憶體塊例如:

int * pn = new int;
// 正確
delete pn;
// 不正確, 因為pn已經釋放過一次了
delete pn;
int num = 123;
int * pn2 = &num;
// 不正確, 因為pn的記憶體不是通過new來分配的
delete pn2;

注意:只能用delete來釋放使用new分配的記憶體, 但是對空指標使用delete是安全的. 

int * pn = new int;
int * pn2 = pn;
delete pn2;

上面的程式碼是沒有問題的, 但是一般來說不要建立兩個指向同一個記憶體的指標, 因為這將增加錯誤的刪除同一個記憶體塊兩次的可能性