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 = #
// 不正確, 因為pn的記憶體不是通過new來分配的
delete pn2;
注意:只能用delete來釋放使用new分配的記憶體, 但是對空指標使用delete是安全的.
int * pn = new int;
int * pn2 = pn;
delete pn2;
上面的程式碼是沒有問題的, 但是一般來說不要建立兩個指向同一個記憶體的指標, 因為這將增加錯誤的刪除同一個記憶體塊兩次的可能性