我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++new与malloc和delete及free动态内存管理及区别介绍

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++new与malloc和delete及free动态内存管理及区别介绍

一般情况-堆上申请普通变量空间

申请堆空间时,实验表明 new/malloc 与 delete/free 是可以混用的,即可以通过free()释放掉new出来的一块内存。

int main() {
	int *p = new int(123);
	delete p;
	//free(p);
}

特殊情况-堆上申请对象空间

class Person{
public:
	Person(){
		cout << "construct call ......" << endl;
	}
	~Person(){
		cout << "destruct call ......" << endl;
	}
private:
	int m_age;
};
int main() {
	Person *ptr = new Person();
	if (ptr != nullptr)
	{
		free(ptr);
	}
	return 0;
}

单步走看内存分布图:

可以看到,执行完free(ptr) 后,内存确实是被释放了。(补充一下:fd作为开始结束的标志,"cd cd cd cd"代表开辟的内存,四个字节)

但是!对于一个对象而言,new和delete关键字还额外做了 调用构造函数和调用析构函数这两个步骤。

可以看到,程序只调用了构造函数(new关键字产生),但是由于使用的是free(),因此并没有调用类中的析构函数。

一般情况-堆上申请普通数组空间

int main() {
	int *ptr = new int[10];
	delete[]ptr;
	//delete ptr;
	return 0;
}

我们知道,用new在堆上申请数组空间,一般delete的时候都需要加上[ ] ,即 delete[ ] 。

但实验表明,如果不涉及到类对象,不加[ ]也同样可以实现空间的释放,加不加[ ]是没有区别的。

特殊情况-堆上申请对象数组空间

int main() {
	Person *ptr = new Person[10];
	delete ptr;
	return 0;
}

当new一个对象数组时,如果没有用delete[ ] ,会发生崩溃报错:

修改成delete [ ] ptr后,程序正常运行,并调用了十次构造函数和十次析构函数:

进一步探索:为什么修改为delete [ ] 就会调用十次析构函数?它是如何知道创建了十个对象就一定会析构十个对象?

查看一下此种情况下的内存分布:

可以看到我们申请的堆对象数组空间(10个),仔细查看改起始地址的前一个地址,按道理这并不属于我们分配的空间,为什么会多一个地址?

0x011E4EC8 ,该地址保存的值显示为16进制,转换为十进制刚好为10(0a 00 00 00)。这个10代表着什么?

不妨修改一下这个地址,0a 00 00 00 修改成 07 00 00 00 后接着单步走:

此时原来的十个地址空间的确是完整的被释放了,但是析构函数只被调用了 7次!正好是自己修改的那个内存地址的值。

到这里可以得出结论: 编译器是如何记录new 创建出来数组对象的个数, 就是简单的在创建空间的前一个地址,记录了创建对象的个数,析构的时候就按照这个地址的值进行析构。

总结

1. 申请一个堆上的对象时,不允许混搭new/delete 必须搭配使用。

2. new [ ] 和 delete [ ] 一定要配套使用,特别是申请对象数组时。

3. vs编译器会在new [ ] 申请对象数组时,在堆开始的前4个字节写入当前数组的长度,用于记录delete [ ]释放时候的析构函数调用。

到此这篇关于C++ new与malloc和delete及free动态内存管理及区别介绍的文章就介绍到这了,更多相关C++动态内存管理内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++new与malloc和delete及free动态内存管理及区别介绍

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++new与malloc和delete及free动态内存管理及区别介绍

这篇文章主要介绍了深入理解C++中的new/delete和malloc/free动态内存管理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-12-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录