news 2026/5/20 8:20:33

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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,就可以显式调用类的构造函数,对一块空间重新初始化。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 8:17:08

3分钟上手Hitboxer:免费解决游戏按键冲突的终极指南

3分钟上手Hitboxer:免费解决游戏按键冲突的终极指南 【免费下载链接】socd Key remapper for epic gamers 项目地址: https://gitcode.com/gh_mirrors/so/socd Hitboxer是一款专业的按键重映射和SOCD处理工具,专门为游戏玩家解决按键冲突问题&…

作者头像 李华
网站建设 2026/5/20 8:16:07

终极指南:如何安全高效地备份和导出微信聊天记录

终极指南:如何安全高效地备份和导出微信聊天记录 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 在数字时代,您的微信聊天记录承载着珍贵的工作沟…

作者头像 李华
网站建设 2026/5/20 8:11:37

【FPGA】高云FPGA PLL锁相环IP核实战:从配置到多时钟域系统验证

1. 高云FPGA PLL锁相环IP核入门指南 第一次接触高云FPGA的PLL_ADV IP核时,我完全被它强大的时钟管理能力震撼到了。简单来说,这个IP核就像是个智能时钟分发器,能把一个输入时钟变成多个不同频率的时钟信号。在实际项目中,我们经常…

作者头像 李华
网站建设 2026/5/20 8:10:35

贝壳第一季净收入189亿:经调净利润16.11亿同比增15.7%

雷递网 乐天 5月19日贝壳今日发布2026年第一季度业绩公告。财报显示,贝壳2026年第一季度贝壳实现净收入189亿元,净利润12.55亿元,同比增长46.7%,经调整净利润达16.11亿元,同比增长15.7%,超出市场一致预期。…

作者头像 李华
网站建设 2026/5/20 8:09:20

Linux驱动开发:模块参数传递机制详解与工程实践

1. 项目概述:驱动安装与参数传递的“暗语”艺术在Linux驱动开发的世界里,把驱动模块加载进内核,就像给一个正在高速运转的精密机器安装一个新的零件。而“安装驱动参数传递”,就是这个安装过程中,我们与内核、与新零件…

作者头像 李华