一.動態內存分配相關知識點
1.堆和棧內存:
堆內存:動態分配的內存位于堆中,它不受作用域限制,由程序員控制其生命周期。
棧內存:局部變量和函數參數等自動分配的內存位于棧中,由編譯器自動管理。
2.new
和delete
操作符:
new
:用于在堆上分配內存,可以分配單個對象或對象數組。
delete
:用于釋放由new
分配的單個對象的內存。
delete[]
:用于釋放由new[]
分配的對象數組的內存。
3.內存泄漏:
如果忘記使用delete
或delete[]
釋放內存,可能會導致內存泄漏,即程序占用的內存不會被釋放,直到程序終止。
4.構造函數和析構函數:
當使用new
創建對象時,相應的構造函數會被調用。
使用delete
或delete[]
釋放對象時,相應的析構函數會被調用,用于清理對象占用的資源。
5.智能指針:
C++11及更高版本引入了智能指針(如std::unique_ptr
,?std::shared_ptr
),它們可以自動管理內存,避免內存泄漏。
6.malloc
和free
函數:
這些是C風格的動態內存分配和釋放函數,但在C++中推薦使用new
和delete
,因為它們能夠調用構造函數和析構函數。
7.動態數組分配:
可以使用new T[n]
來分配一個包含n個T類型的對象的數組,并使用delete[]
來釋放這個數組。
二.關于構造與析構函數的調用代碼實例
#include<iostream>using namespace std;
class Point {
public:Point() :x(10), y(10) {cout << "調用Point給出的默認構造函數" << endl;}Point(int x, int y) :x(x), y(y) {cout << "調用Point含參構造函數" << endl;}~Point() {cout << "調用Point析構函數" << endl;}void show() const {cout << x << " " << y << endl;}
private:int x, y;
};class Point2 {
public:~Point2() {cout << "調用Point2析構函數" << endl;}void show() const{cout << x << " " << y << endl;}
private:int x, y;
};int main() {cout << "不給出參數列表" << endl;//new動態內存分配,申請內存,成功則返回一個指向新分配內存的首地址(申請失敗出現異常)Point* ptr1 = new Point;(*ptr1).show();//防止“內存泄漏”,但是delete是“釋放指針所指向的內存空間,是刪除new對象,而不是刪除指針本身”//調用new建立對象的析構函數delete ptr1;//用戶給出了默認構造函數//不能重復聲明指針ptr1 = new Point();(*ptr1).show();delete ptr1;cout << "給出參數列表" << endl;Point* ptr2 = new Point(1, 4);(*ptr2).show();delete ptr2;//用戶沒給出默認構造函數,調用系統的(此時類里面不能有用戶給出的無參數或有參數構造函數)//無括號時,單純調用默認構造函數,不初始化Point2* ptr3 = new Point2;ptr3->show();delete ptr3;//有括號時,在調用默認構造函數時,會自動初始化元素為0,并且遞歸初始化ptr3 = new Point2();ptr3->show();delete ptr3;cout << "------1------" << endl;//動態創建對象數組//ptr相當與一個數組名,數組中的每個元素都是指向Point類的指針Point* ptr = new Point[2];ptr[0].show();ptr[1].show();//注意delete格式delete[]ptr;
}
//終端輸出
不給出參數列表
調用Point給出的默認構造函數
10 10
調用Point析構函數
調用Point給出的默認構造函數
10 10
調用Point析構函數
給出參數列表
調用Point含參構造函數
1 4
調用Point析構函數
-842150451 -842150451
調用Point2析構函數
0 0
調用Point2析構函數
------1------
調用Point給出的默認構造函數
調用Point給出的默認構造函數
10 10
10 10
調用Point析構函數
調用Point析構函數
三.動態數組類
#include<iostream>
//擁有“assert”“斷言”:
//可以判斷一個表達式的值是否為true,如果不為true,程序會終止并且報告錯誤地點
#include<cassert>
using namespace std;
class Point {
public:Point() :x(10), y(10) {cout << "調用Point給出的默認構造函數" << endl;}Point(int x, int y) :x(x), y(y) {cout << "調用Point含參構造函數" << endl;}~Point() {cout << "調用Point析構函數" << endl;}void show() const {cout << x << " " << y << endl;}
private:int x, y;
};
//動態數組類
class ArrayOfPoints {
private:Point* points; //指向動態數組首地址int size; //數組大小
public:ArrayOfPoints(int size) :size(size) {points = new Point[size];}~ArrayOfPoints() {cout << "Deleting..." << endl;delete[]points;}//獲取下標為Index的元素//返回引用可以對該下標元素進行修改Point& element(int index) {assert(index >= 0 && index < size); //下標越界程序立即停止return points[index];}
};int main() {int count;cin >> count;//創建對象數組ArrayOfPoints point(count);//通過類安全的訪問數組成員point.element(2).show();//point.element(10).show();cout << "Ending..." << endl;return 0;
}
四.動態創建多維數組
#include<iostream>
using namespace std;
int main() {//cp是一個指向一個二維的9x8的數組的指針,定義了一個cp[8]float(*cp)[9][8] = new float[8][9][8];for (int i = 0; i < 8; i++) {for (int j = 0; j < 9; j++) {for (int k = 0; k < 8; k++) {//以指針形式數組元素*(*(*(cp + i) + j) + k) = static_cast<float>(i * 100 + j * 10 + k);}}}for (int i = 0; i < 8; i++) {for (int j = 0; j < 9; j++) {for (int k = 0; k < 8; k++) {//將指針cp作為數組名使用,訪問數組下標cout << cp[i][j][k] << " ";}cout << endl;}cout << endl;}// 注意刪除格式delete[] cp;return 0;
}