一.动态内存分配相关知识点
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;
}