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