当前位置:网站首页>内存管理A4
内存管理A4
2022-07-27 16:29:00 【刘敬一如】
首先,写博客要一气呵成,不要托两三天,当天的问题当天解决吸收好。然后要有耐心,学习是得有一份耐心的。
本文一些内容参考该链接:C++内存管理(超长,例子很详细,排版很好)_caogenwangbaoqiang的博客-CSDN博客_c++ 内存管理
(一):C++内存包括内核空间,栈,内存映射段,堆,数据段,代码段。
1.首先这里的内存是一个虚拟映射的空间。而物理上的内存则取决于硬件设备的性能。程序跑在操作系统上,也会受内存影响。内存的大小与执行程序的系统有关。在32位程序下,绝大多数内存存在于堆上,栈一般几mb,所以我们常提到因为递归太深,栈溢出的报错。
2.这五个主要的区的作用:内核空间(与操作系统有关,暂不做了解),代码段:用来放可执行代码和只读常量。这里一般是不可被修改的部分。
栈和堆涉及动态内存分配。栈是向下生长的,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
堆是向上生长的。存放由new分配的内存块,他们的释放由我们的应用程序控制,一般只有一个new和一个delete对应。如果程序员没有释放程序掉,那么程序结束后,该操作系统就会自动回收。
数据段全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
还有一些,内存映射段,这一段区域会用来存放动态库和静态库。
(二)区别
1.堆与栈。
void f()
{
int *p=new int[5]; //含义:在栈上的一个指针指向堆的内存,会先确定分配在
堆上的内存的大小,然后再调用operate new 去堆上申请内存
然后返回指向这块内存上的首地址
本质区别:是由于栈内存是由编译器管理的,堆内存是由程序员维护的。对比之下,栈更加结构化一些。体现在,栈先进后出,按照执行步骤压栈弹栈栈销毁,所以有序的指令性分配和释放保证了栈的分配都是有序的。但也静态内存分配(编译好的)和动态内存分配,动态内存分配是由malloc函数进行分配。 而堆的分配和释放是不连续的,导致堆中存在很多碎片。
2.delete和new:
(三)C++中的内存管理方式
针对于C语言中的malloc--和free,C++中我们完善出了new//和delete。
A.new~delete与malloc~free对比【第一组实验】
B.new~delete与malloc~free 开内存失败【第二组实验】
C.定位new表达式

[A]由分析得:1.new和delete分别调了构造函数与析构函数。而malloc和free没有。并且与是否是内置类型无关。2.推测原理。指针的作用。为什么要通过删除和实例化指针来开辟和释放空间?
(1)原理:在栈上的一个指针指向堆的内存,会先确定分配在堆上的内存的大小,然后再调用operate new 去堆上申请内存,然后返回指向这块内存上的首地址。
(2)new和delete会调用构造函数和析构函数
/*
operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。
*/
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
// try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{
// report no memory
// 如果申请内存失败了,这里会抛出bad_alloc 类型异常
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
/*
operator delete: 该函数最终是通过free来释放空间的
*/
void operator delete(void *pUserData)
{
_CrtMemBlockHeader * pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK); /* block other threads */
__TRY
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
_free_dbg( pUserData, pHead->nBlockUse );
__FINALLY
_munlock(_HEAP_LOCK); /* release other threads */
__END_TRY_FINALLY
return;
}
//free的实现
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
[B]operator new 实际也是通过malloc来申请空间,如果malloc申请空间 成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的
operator new 与operator delete函数:new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的 全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局 函数来释放空间。
#include<iostream>
using namespace std;
int main()
{
try
{
char* p = new char[0x8fffffff];
//char* p = new char[08ffffffff];
printf("%p\n", p);
}
catch (const exception& e)
{
cout << "内存申请失败" << endl;
}
return 0;
}对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。
class Test
{
public:
Test()
: _data(0)
{
cout<<"Test():"<<this<<endl;
}
~Test()
{
cout<<"~Test():"<<this<<endl;
}
private:
int _data;
};
void Test()
{
// pt现在指向的只不过是与Test对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执
行
Test* pt = (Test*)malloc(sizeof(Test));
new(pt) Test; // 注意:如果Test类的构造函数有参数时,此处需要传参
}边栏推荐
- Big enemies, how to correctly choose the intended enterprises in the new testing industry?
- Unity learning notes (rigid body physics collider trigger)
- C interface knowledge collection suggestions collection
- Power control
- Unity显示Kinect捕获的镜头
- Basic use of Nacos (1) - getting started
- ES6 learning notes (1) - quick start
- How can I get started quickly when I change my career to soft testing and job hopping to a new company?
- ref 关键字的用法
- IDEA成功连接Database但不显示表怎么办
猜你喜欢

MySQL学习笔记(2)——存储过程与存储函数

Extension of regular expression

Nacos的基本使用(1)——入门

阿里云视频点播服务的开通和使用

阿里云对象存储OSS的开通和使用

Performance analysis of continuous time systems (2) - second order system performance improvement methods PID, PR

Unity shows Kinect captured shots

Kinect for Unity3D——BackgroundRemovalDemo学习

kettle switch / case 控件实现分类处理

ES6学习笔记(1)——快速入门
随机推荐
2022 Ningde Vocational College Teachers' practical teaching ability improvement training - network construction and management
kettle EXCEL 累计输出数据
`this.$ Emit ` the child component passes multiple parameters to the parent component
浅谈基本的网络基本故障和问题排查
怎样产生标准分布或高斯分布的随机数
An experience
Selenium automated test interview questions family bucket
Performance analysis of continuous time systems (2) - second order system performance improvement methods PID, PR
Double insurance for line breaking
Questions about webservice
Mongodb learning notes (1) - install mongodb and its related configurations
微机原理学习笔记-常见寻址方式
Big enemies, how to correctly choose the intended enterprises in the new testing industry?
Some advice for NS2 beginner.
The great idea of NS2
v-if,v-else,v-for
What if idea successfully connects to the database without displaying the table
C语言打印菱形
asp.net 的经验
Basic concepts of Nacos and single machine deployment