当前位置: 首页 > news >正文

C++中动态内存管理和泛型编程

一、C/C++内存区域划分

1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。

2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。

3. 堆用于程序运行时动态内存分配,堆是可以上增长的。

4. 数据段--存储全局数据和静态数据。

5. 代码段--可执行的代码/只读常量。

二、常见变量存储区域

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

intglobalVar = 1;//全局变量中在静态区

staticintstaticGlobalVar = 1;//静态区

voidTest()

{

staticintstaticVar = 1;//静态区

intlocalVar = 1;//栈区

intnum1[10] = { 1, 2, 3, 4 };//栈区

charchar2[] ="abcd";//栈区,*char2在栈区

constchar* pChar3 ="abcd";//指针在栈区,*pchar3在常量区

int* ptr1 = (int*)malloc(sizeof(int) * 4);//指针在栈区,*ptr1在堆区

int* ptr2 = (int*)calloc(4,sizeof(int));///栈区

int* ptr3 = (int*)realloc(ptr2,sizeof(int) * 4);//栈区

free(ptr1);

free(ptr3);

}

三、new和delete

1、new和delete的使用方式

1

2

3

4

5

6

7

8

9

10

11

12

13

intmain()

{

int* p1 =newint;//在堆区申请一个int大小的空间,不会初始化

int* p2 =newint(0);//申请并初始化为0

deletep1;

deletep2;

int* p3 =newint[10];//在堆区申请一块10个int大小的空间,未初始化

int* p4 =newint[10]{ 1,2,3,4 };//初始化为{1,2,3,4,0,0,0,0,0,0}

delete[] p3;

delete[] p4;

return0;

}

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],一定要匹配起来使用。

2、new、delete和malloc、free的区别

1、对于内置类型,没有区别。

2、new和delete是C++的关键字/操作符,而malloc和free是C语言的库函数。

3、对于自定义类型,相比于malloc和free,new和delete会额外调用类中的构造函数和析构函数。

4、malloc的返回值是void*,使用时需要强转,new后边跟的是空间的类型,所以new不需要强转。

5、malloc失败返回空指针,需要判空;new失败抛异常,需要捕获异常。

3、new的原理

new等于operator new()+构造函数。operator new()不是new运算符的重载,因为参数没有自定义类型。它是一个库里的全局函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

void*__CRTDECL operatornew(size_tsize) _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 类型异常

staticconststd::bad_alloc nomem;

_RAISE(nomem);

}

return(p);

}

从底层代码可以看出operator new()是对malloc的封装,如果malloc失败,将会抛出异常。

4、delete的原理

delete等于operator delete()+析构函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

//operator delete: 该函数最终是通过free来释放空间的

voidoperatordelete(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 );//调用free()

__FINALLY

_munlock(_HEAP_LOCK);/* release other threads */

__END_TRY_FINALLY

return; }

//free的实现

#define free(p) _free_dbg(p, _NORMAL_BLOCK)

从底层代码可以看出operator delete()调用了free。

所以针对内置类型或无资源的类对象delete时,使用delete和free效果相同。但对于有资源需要释放的对象时,直接使用free虽然释放了对象的空间,但对象内部的资源还未被清理,导致内存泄漏!这种情况必须使用delete。

5、new T[N]原理

1、new T[N]调用operator new[]

2、operator new[]调用operator new完成N个对象空间的开辟。

3、调用N次构造函数完成N个对象的初始化。

6、delete[]原理

1、调用N次析构函数完成N个对象资源的清理工作。

2、调用operator delete[]

3、operator delete[]调用operator delete完成整段空间的释放。

四、定位new

1、定位new的概念

对于一个类,我们可以显式的去调用类的析构函数,但是不能显式调用构造函数,那么使用定位new,就可以显式调用类的构造函数,对一块空间重新初始化。


http://www.jsqmd.com/news/850275/

相关文章:

  • 基于ssm的萌宠宜家商城系统(10064)
  • PiMAE:基于掩码自编码器的跨模态3D感知预训练技术解析
  • 实验干货:多因子细胞因子流式检测CBA技术
  • SMUDebugTool深度解析:AMD平台硬件调试与性能优化实战指南
  • c#基础知识合集06 类 值类型和引用类型 方法定义和调用
  • 抖音无水印批量下载终极指南:从零基础到专业用户的完整成长路径
  • 5个步骤掌握小程序源码解析:unveilr深度技术指南
  • 如何在3分钟内完成OBS多平台直播:终极免费插件完整指南
  • SAP 梳理思路
  • 紧跟市场黄金行情报价 合肥专业黄金饰品回收大价优 - 奢侈品回收测评
  • Linux内存压缩技术:ZRAM与ZSWAP原理、选型与性能调优指南
  • css的定位布局
  • GPR:面向大规模广告推荐的生成式预训练单模型范式Who is Zhongyao Tuo
  • 手把手教你用GD32E230驱动LED:从点亮到闪烁的完整代码与SysTick延时配置
  • 9周盒模型的外三层的结构 - feng
  • oiioii邀请码 2026年5月20号最新
  • 第十周 - qwerzxcv-
  • NoSQL数据库原理与应用
  • 避坑指南:Houdini风格化树木导入Unity URP后,光照和裁剪效果不对怎么办?
  • 终极指南:如何3秒快速预览Office文件而无需安装完整Office套件
  • 2026年性价比高的大中电机防爆电机厂家推荐,上海炬越能源工程有限公司好不好 - mypinpai
  • 2026年阿里云OpenClaw/Hermes Agent配置Token Plan快速上手指南
  • 2026年想快速提分?邵阳这些高复学校或许能帮你实现梦想!
  • 私域大师最好用的企微SCRM工具
  • G-Helper:华硕笔记本终极轻量级控制工具完整指南
  • 10分钟带你完成:Claude Code CC Switch 接入DeepSeek-V4
  • 基于 Nginx 实现一个灰度上线系统
  • ComfyUI v0.21.1:最新版本发布,模型、节点、工作流与稳定性全面升级
  • BBDown:命令行驱动的B站视频下载完整方案
  • 政企级无人机管理系统,如何用一套方案搞定多行业巡检?