1. 程式人生 > >c++之動態記憶體分配

c++之動態記憶體分配

1.先拿指標為例,搞明白指標賦值的含義。給指標賦值就相當於是改變指標的地址,就是改變指標所指向的記憶體。

#include <iostream>
using namespace std;

int main()
{
	int b1 = 0, b2 = 4;
	int *a1 = &b1;
	int *a2 = &b2;
	cout << "賦值前a1和a2的地址:" << endl;
	cout << "a1的值為 " << a1 << " a1指向的元素為" << *a1 << endl;
	cout << "a2的值為 " << a2 << " a2指向的元素為" << *a2 << endl;

	a1 = a2; //這種賦值之後,a1的地址變了,因而指向的元素也發生了變化
	cout << "賦值後a1和a2的地址:" << endl;
	cout << "a1的值為 " << a1 << " a1指向的元素為" << *a1 << endl;
	cout << "a2的值為 " << a2 << " a2指向的元素為" << *a2 << endl;

	return 0;
}

程式的輸出為:


2.採用new和delete動態申請和釋放記憶體

在申請動態記憶體的時候,有幾個new,就表示申請了幾塊記憶體,就要有幾個delete,來刪除這些指標所指向的記憶體。這樣才能儘可能保證記憶體不洩露。因而如果程式中有對指標的賦值操作,那麼在對該指標賦值之前,要先將該指標所指向的那塊記憶體刪除。

這裡要注意:在釋放動態申請的記憶體時一定要注意,如果程式中在進行指標的賦值之後,兩個指標指向相同的動態分配物件,如果對其中一個指標進行了delete操作,物件的記憶體就被歸還給自由空間了,這時如果再delete第二個指標,自由空間就會被破壞。出現同一塊記憶體被釋放兩次的錯誤。這個在釋放動態分配的記憶體時尤其要注意。詳細可見下面程式碼。

當delete一個指標之後,指標就變成無效的了,雖然指標已經無效,但是很多機器上指標仍然儲存著(已經釋放了的)動態記憶體的地址,變成了野指標。解決方法:可以在delete之後,將nullptr賦予指標,這樣指標就不指向任何物件。這是在程式設計時防止記憶體洩露的好習慣,要養成在delete之後隨時給指標賦為nullptr的習慣。

#include <iostream>
using namespace std;

int main()
{
	//動態申請記憶體,用new和delete申請和釋放記憶體
	int *q = new int(10), *r = new int(4);

	cout << "賦值前r和q的地址:" << endl;
	cout << "q的值為 " << q << "q指向的元素是 " << *q << endl;
	cout << "r的值為 " << r << "r指向的元素是 " << *r << endl;

	//這裡為防止記憶體洩漏,在對指標賦值之前,要先將被賦值的指標所指向的那塊記憶體刪除。即增加delete r;
	delete r;
	r = nullptr; //這裡放這雖然沒用,為保持良好習慣就這麼用吧
	r = q;
	cout << "賦值後r和q的地址:" << endl;
	cout << "q的值為 " << q << "q指向的元素是 " << *q << endl;
	cout << "r的值為 " << r << "r指向的元素是 " << *r << endl;

	delete q;  //這裡尤其要注意,不要對同一塊記憶體釋放兩次,由於賦值後,兩個指標指向同一塊記憶體,所以對其中一個指標進行delete,就把物件的記憶體歸還給自由空間了
	q = nullptr;  
	//delete r;  //這句話是不能加的歐,會造成同一塊記憶體釋放兩次的錯誤。

	return 0;
}

程式輸出為:


3.採用智慧指標。智慧指標和常規指標的區別在於:智慧指標會自動釋放所指向的物件。更容易的使用動態記憶體。

#include <iostream>
#include <memory>
using namespace std;

int main()
{
	//若用智慧指標來進行動態記憶體管理,程式執行結束後,自動釋放指標所指向物件的記憶體。

	auto q2 = make_shared<int>(10), r2 = make_shared<int>(4);
	cout << "賦值前r2和q2的地址:" << endl;
	cout << "q2的值為 " << q2 << " q2指向的元素是 " << *q2 << endl;
	cout << "r2的值為 " << r2 << " r2指向的元素是 " << *r2 << endl;

	r2 = q2;
	cout << "賦值後r2和q2的地址:" << endl;
	cout << "q2的值為 " << q2<< " q2指向的元素是 " << *q2 << endl;
	cout << "r2的值為 " << r2 << " r2指向的元素是 " << *r2 << endl;

	return 0;
}

程式輸出為: