99 C++内存高级话题。new/delete的进一步认识 整理

1. new 初始化的整理。

class Teacher120 {
public:
	Teacher120() {
		cout << "teacher120 moren 构造函数" << endl;
	}
	Teacher120(int age):m_age(m_age) {
		cout << "teacher120 构造函数" << endl;
	}
	~Teacher120() {
		cout << "teacher120 析构函数" << endl;
	}

	int m_age;
};

void main() {
	//1. new 初始化的整理。
	//对于普通类型
	int *point = new int;//初值随机
	int *point1 = new int();// 初值是0.
	int *point2 = new int(100);// 初值是100.

	delete point;
	delete point1;
	delete point2;

	//对于自带的类,例如 string
	string* str1 = new string; //初值为""
	string* str2 = new string();//初值为""
	string* str3 = new string("abc");//初值为"abc"
	string* str4 = new string(5,'a');//初值为"aaaaa"
	int str4len = str4->length(); //大小为5
	cout << "str4len" << str4len << endl;
	delete str1;
	delete str2;
	delete str3;
	delete str4;


	//对于自定义类,需要调用Teacher120的构造函数,
	//当前Teacher120没有空的构造函数,因此要传参数
	Teacher120 * pt = new Teacher120(80);
	delete pt;
	//  运行结果:
	//  teacher120 构造函数
	//	teacher120 析构函数

	//类的集合
	Teacher120 * pt1 = new Teacher120[3];
	delete []pt1;
	//  运行结果:
	//  teacher120 moren 构造函数
	//	teacher120 moren 构造函数
	//	teacher120 moren 构造函数
	//	teacher120 析构函数
	//	teacher120 析构函数
	//	teacher120 析构函数

	//对于集合,先来看正常的vector怎么使用
	vector a;
	a.push_back(2);
	a.push_back(5);
	cout << a[0] << endl;  //2 
	vector::iterator it = a.begin();
	for (; it < a.end();it++) {
		cout << "  it  = " << *it << endl;
	}
	//it = 2
	//	it = 5


	//对于集合,指针
	vector * pv = new vector;
	pv->push_back(10);
	pv->push_back(20);
	pv->push_back(30);
	
	for (vector::iterator it1 = pv->begin(); it1 < pv->end();it1++) {
		cout << "it1 = " << *it1 << endl;
	}
	//it1 = 10
	//	it1 = 20
	//	it1 = 30

	delete pv;

	//对于集合数组,pv2指向一个 三个vector 组成的,我们假设每一个vector中都有5个int 组成。
	
	//注意的是:这里 pv 和 pv2 都是前面都是  vector * 类型
	vector *pv2 = new vector[3];
	for (size_t i = 0; i < 3; i++)
	{
		for (int k = 0; k < 5;k++) {
			pv2[i].push_back(k);
		}
	}

	for (int i = 0; i < 3; i++) {
		for (vector::iterator it = pv2[i].begin(); it < pv2[i].end();it++) {
			cout << "   " << *it;
		}
		cout << endl;
	}

	//0   1   2   3   4
	//	0   1   2   3   4
	//	0   1   2   3   4


	delete[] pv2;
	char *p = nullptr;
	delete p;//空指针可以多次delete
	delete p;

	//总结: new 和delete 要成对使用,delete的租用是回收用new 分配的内存

}

1.1 new 类对象时 加括号,和不加括号的区别是?

对于普通类型:

    int *point = new int;//初值随机
    int *point1 = new int();// 初值是0.
    int *point2 = new int(100);// 初值是100.

对于自定义类,如果是个空类,类中啥有没有,那么如下两种没有区别

Teacher *ptea = new Teacher;

Teacher *ptea1 =new Teacher();

对于自定义类,如果有成员变量int mage,但是没有自己写的构造函数

Teacher *ptea = new Teacher; //mage是随机值

Teacher *ptea1 =new Teacher(); //mage = 0;

对于自定义类,如果有成员变量int mage,也有自己写的构造函数

Teacher *ptea = new Teacher; //mage是随机值,这是因为编译器认为你既然写了构造函数,就应该在构造函数中完成自己成员的初始化,而不是依赖于我

Teacher *ptea1 =new Teacher(); //mage是随机值,这是因为编译器认为你既然写了构造函数,就应该在构造函数中完成自己成员的初始化,而不是依赖于我

2.new /delete是什么?

关键字/运算符,不是函数

3.new做了两件事:使用反汇编查看干了啥

3.1.分配内存,通过 operator new()函数实现

3.2.调用构造函数初始化内存

class Teacher34 {
public:
	Teacher34() {
		cout << "Teacher34 的构造函数被调用" << endl;
	}
	~Teacher34() {
		cout << "Teacher34 的析构函数被调用" << endl;
	}
};

void main(){
	Teacher34 *ptea = new Teacher34;
	cout << "duandian zaizheli" << endl;
}

99 C++内存高级话题。new/delete的进一步认识 整理_第1张图片

然后在 operator new 这一行按下 F11进去看,就会看到malloc语句

99 C++内存高级话题。new/delete的进一步认识 整理_第2张图片

4.delete 做了两件事,使用反汇编查看干了啥

4.1.调用析构函数

4.2.释放内存,通过operator delete()函数显示

class Teacher34 {
public:
	Teacher34() {
		cout << "Teacher34 的构造函数被调用" << endl;
	}
	~Teacher34() {
		cout << "Teacher34 的析构函数被调用" << endl;
	}
};

void main(){
	Teacher34 *ptea = new Teacher34;
	
	cout << "11111 11111" << endl;
	delete ptea;
	cout << "22222 22222" << endl;
	ptea = nullptr;

	cout << "duandian zaizheli" << endl;
}

在delete ptea这一行加上断点,查看这一行到底干了啥?

99 C++内存高级话题。new/delete的进一步认识 整理_第3张图片

99 C++内存高级话题。new/delete的进一步认识 整理_第4张图片

继续F11

99 C++内存高级话题。new/delete的进一步认识 整理_第5张图片

3,4 的另一种验证方法 

ctrl+鼠标点击 进入查看源码,但是只能看到调用了 operator new

5.new/delete  和 malloc() /free()的区别

new 、delete 是关键字/运算符。会调用构造函数/析构函数

malloc(),和 free()是函数。从C 语言继承,没有构造函数/析构函数的概念

6.new 出来的内存多大,delete的时候是怎么知道的呢?

例如

int *p = new int();// new 出来的是int大小 - 4个字节,那么delete 的时候,delete怎么知道要销毁4个字节呢?

new 内部有机制,会记住大小,delete的时候会先通过p的地址查找到这块内存,然后根据这个值删除对应大小的空间

7.关于申请和释放数组的问题

对于基础类型的数组

int *parr = new int[3];

delete [] parr;//如果不释放,就会有3*4 = 12个字节的 内存泄漏

对于自定义类型数组,会多出来4个字节保存数组的大小

class A{

}

假设A 类中啥都没有,那么这个A 类会占用1个字节的大小

那么意味着:

A * arrclass = new A();

delete arrclass; 如果不释放,会有1个字节被泄露。

但是如果自定义类有析构函数,且new 出来的是数组,那么会额外占用4个字节的大小

class B{

        public:

                ~B(){ };

}

B * arrclassBBB = new B[3]();

//如果没有delete [] arrcassBBB 的情况下,会有7个字节的内存泄漏

每个B 泄漏一个,然后还有一个4字节,这4个字节是记录该数组有几个数字,也就是3.因此泄漏7个字节。

你可能感兴趣的:(c++,算法,开发语言)