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

C++内存布局及动态内存分配

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

C++内存布局及动态内存分配

动态内存分配

C++和C语言的内存分区一样。

text和data段都在可执行文件中,由系统从可执行文件中加载;而bss段不在可执行文件中,由系统初始化。

Stack: 栈区,存放局部变量,按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,但自由性差,空间不大。

Heap: 堆区,由程序员自己自由申请的空间,按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。
每个线程都会有自己的栈,但是堆空间是共用的。

BSS区(未初始化数据段):存放为初始化的全局变量和静态变量,只占用内存空间,不占用文件空间,不给该段的数据分配空间,仅仅是记录了数据所需空间的大小。

DATA(初始化的数据段)(RW):可读写数据,存放初始化的静态变量和全局变量,为数据分配空间,数据保存在目标文件中,const定义的全局变量存放在 rodata段。

常量区(rodata):存放字符串,const修饰的全局变量也储存在rodata区内,而const修饰的局部变量依然在栈上。

静态变量是地址向下增长,全局常量是地址向上增长。

  • 调用函数,形成栈帧—函数返回,释放栈帧
  • 临时变量在栈帧中,释放栈帧后临时变量就可被覆盖,也就是被释放的掉
  • 函数的返回值是通过寄存器返回给调用方
  • C有字符串但没有字符串类型
  • 循环时尽量使得外侧少,内侧多,这样可以减少循环指令跳转

new和delete是C++定义的内存分配的操作符,C语言的动态内存分配函数malloc和free在C++中依然可以使用,new和delete解决了一些malloc和free无法解决的问题。

new int;   //new一个对象

new int [10];  //new十个对象
 
new int(10);      //new一个对象初始化成10

new int[10]{10,1,2,3};    //new十个对象 初始化为(10,1,2,3,0,0,0,0,0,0)

malloc和new区别:

  • malloc只开辟空间不初始化 ----- new开辟空间调用构造函数
  • malloc失败会返回空指针 ------ new失败了抛异常
  • malloc申请空间时需要计算 ------ new不需要
  • malloc的返回值为void*必须要强转 ------ new不需要因为后跟的是空间的类型

free和delete区别:

  • free只释放自己的空间如自己创建指针指向的空间不会被释放 ------ delete会调用析构函数 + 释放空间

new的底层其实是调用了operator new + 构造函数,然后operator new会调用malloc,如果malloc失败operator new会直接抛出异常。

delete的底层是调用operator delete + 析构函数 ,然后operator delete调用free如果free失败operator delete会直接抛出异常。

可以在汇编代码看到确实new调用了operator new。

如果遇到一个已经开辟好的空间,但是没有初始化,现在我们想要初始化,就要使用到replacement - new 重定位new 对这片空间显示调用构造函数。

int main()
{
	Date* a = (Date*)malloc(sizeof(Date));
	new (a)Date(1999, 1, 1);//  重定位new

	cout << *a << endl;
	
	free(a);

	return 0;
}

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

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

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