栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 内存管理

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 内存管理

C++ 内存管理

文章目录
  • C++ 内存管理
  • 前言
  • 一 、C/C++ 内存管理
      • new/delete 操作自类型
      • new/delete 操作自定义类型
      • 注意点:
      • new/delete 底层原理
        • operator new/operator delete 全局函数
      • operator new[] / operator delete[]
      • 定位new (replacement-new)
      • 面试题:new/delete 和 malloc/free 的区别


前言

C++兼容C的大多数语法,malloc/calloc/free 在C++也可以继续使用,但是一些场景下无法满足需求,于是提供了new/delete 操作符进行动态内存管理。


一 、C/C++ 内存管理
new/delete 操作自类型

对于操作自定义类型,用malloc或者new申请空间没什么区别,都不会对所申请的内存空间初始化。但malloc需要手动给出所申请空间大小,还需要手动强转,没有new方便。

	//malloc申请10个int大小内存
	int* ptr1 = (int*)malloc(sizeof(int) * 10);
	//free释放
	free(ptr1);

	//new申请10个int大小内存
	int* ptr2 = new int[10];
	//delete[] 释放
	delete[] ptr2;


new/delete 操作自定义类型

对于操作自定义类型,malloc只申请了空间,并没有对空间进行初始化,free也仅仅释放了空间。new不仅仅申请了空间,还调用了其默认构造初始化 (如果不提供默认构造,则无法通过编译,编译器提供的默认无参构造,我们手动给出的无参构造,参数列表全缺省的构造,都为默认构造) 。delete时,也调用了其析构函数对其进行资源释放。

class Person
{
public:

	Person(string name = "张三", int age = 11):_name(name),_age(age) {}

private:
	string _name;
	int _age;
};

int main()
{
	Person* p1 = (Person*)malloc(sizeof(Person) * 10);
	Person* p2 = new Person[10];

	delete[] p2;
	free(p1);
}

注意点:

malloc/free 和 new/delete 一定要成对使用,混合着用很容易引起程序奔溃或者内存泄露,虽然在某些情况不会有问题。

	int* ptr1 = (int*)malloc(sizeof(int) * 10);
	delete ptr1; // 对于内置类型,正常释放,也不会有内存泄露,不建议这样用


new/delete 底层原理
operator new/operator delete 全局函数

new在底层了调用了operrator new这个全局函数,其底层其实也是调用了malloc申请堆空间,但其对申请空间失败的处理与malloc不同,malloc申请失败返回null,new申请失败则会以抛异常的方式处理。

operator delete 底层也是对free的封装。

new 一共做了两件事,1. 调用operator new申请空间 2. 调用了析构函数。

delete 1. 调用析构函数释放资源,2. operator delete释放空间


我们也可以手动调用operator new /delete 申请,释放空间,其使用方式和malloc free相同。

	Person* p2 = (Person*)operator new(sizeof(Person) * 10);
	operator delete(p2);


operator new[] / operator delete[]

operator new[] 底层调用operator new 完成N个对象的空间申请,还调用了N次构造函数对所申请空间完成初始化。

operator delete[] 对所要释放空间调用N次析构函数释放对象的资源,底层调用operator delete完成释放。



定位new (replacement-new)

定位new的作用是在已申请的空间上调用构造函数初始化对象。

	//malloc只空间,没有完成初始化
	Person* p1 = (Person*)malloc(sizeof(Person));
	//在已经申请的空间上调用构造函数进行初始化
	new(p1)Person("李四",22);

	Person* p2 = (Person*)malloc(sizeof(Person) * 3);
	for (int i = 0; i < 3; i++)
		new(p2 + i) Person(pArr1[i]); //调用拷贝构造对其初始化



面试题:new/delete 和 malloc/free 的区别
  1. malloc申请空间需要手动给出所申请空间大小,并且需要强转,new只需要给出申请对象的个数。
  2. malloc不会对申请的空间进行初始化,无论是内置还是自定义类型,而new会对自定义类型调用其构造函数对其初始化,而内置类型不会。
  3. 从本质上看,new其实就是对malloc的封装+构造函数,delete就是析构+free的封装。
  4. 从申请失败的处理方式上,malloc申请空间失败返回NULL,new申请失败会以抛异常的方式处理。

斜体样式

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/347125.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号