c++之動態記憶體分配
阿新 • • 發佈:2019-01-05
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;
}
程式輸出為: