C++全面覆盖内存管理知识讲解

 更新时间:2022年06月18日 08:40:18   作者:努力变好的zz  
本章主要介绍C语言与C++的内存管理,以C++的内存分布作为引入,介绍C++不同于C语言的内存管理方式(new delete对比 malloc free),感兴趣的朋友来看看吧

前言

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

一、C++内存管理方式

1.1new/delete操作内置类型

void Test()
{
// 动态申请一个int类型的空间
int* ptr4 = new int;
// 动态申请一个int类型的空间并初始化为10
int* ptr5 = new int(10);
// 动态申请10个int类型的空间
int* ptr6 = new int[3];
delete ptr4;
delete ptr5;
delete[] ptr6;
}

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]

二、operator new与operator delete函数

2.1operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator 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)

通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

二、new和delete的实现原理

2.1内置类型

如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

2.2 自定义类型

new的原理

  • 调用operator new函数申请空间
  • 在申请的空间上执行构造函数,完成对象的构造

delete的原理

  • 在空间上执行析构函数,完成对象中资源的清理工作
  • 调用operator delete函数释放对象的空间

new T[N]的原理

  • 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
  • 在申请的空间上执行N次构造函数

delete[]的原理

  • 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
  • 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

到此这篇关于C++全面覆盖内存管理知识讲解的文章就介绍到这了,更多相关C++内存管理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Qt信号与槽知识点总结归纳

    Qt信号与槽知识点总结归纳

    信号和槽是一种高级接口,应用于对象之间的通信,它是QT的核心特性,下面这篇文章主要给大家介绍了关于Qt信号与槽知识点总结归纳的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • C++中点操作符和箭头操作符的使用详解

    C++中点操作符和箭头操作符的使用详解

    本篇文章介绍了,C++中点操作符和箭头操作符的使用详解。需要的朋友参考下
    2013-05-05
  • 利用Matlab绘制优美的k线图

    利用Matlab绘制优美的k线图

    本期又是一个花里胡哨的数据可视化,前两天刷到了耐克的视觉设计师Gladys Orteza绘制的k线图作品,把沉闷的股票图变成了精彩的风景,但是那些大部分是真的完全看不清,我这里挑选了几个能看清的k线图风格将其用MATLAB进行了实现
    2022-10-10
  • C语言实现三子棋实例代码

    C语言实现三子棋实例代码

    大家好,本篇文章主要讲的是C语言实现三子棋实例代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • C++中std::count函数介绍和使用场景

    C++中std::count函数介绍和使用场景

    std::count函数是一个非常实用的算法,它可以帮助我们快速统计给定值在指定范围内的出现次数,本文主要介绍了C++中std::count函数介绍和使用场景,感兴趣的可以了解一下
    2024-02-02
  • C++关于构造函数可向父类或者本类传参的讲解

    C++关于构造函数可向父类或者本类传参的讲解

    今天小编就为大家分享一篇关于C++关于构造函数可向父类或者本类传参的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 浅谈C语言函数调用参数压栈的相关问题

    浅谈C语言函数调用参数压栈的相关问题

    下面小编就为大家带来一篇浅谈C语言函数调用参数压栈的相关问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • C++中的HTTP协议问题

    C++中的HTTP协议问题

    这篇文章主要介绍了C++中的HTTP协议问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • 函数式宏定义与普通函数的区别

    函数式宏定义与普通函数的区别

    尽管函数式宏定义和普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配和释放栈帧、传参、传返回值等一系列工作,因此那些简短并且被频繁调用的函数经常用函数式宏定义来代替实现
    2013-10-10
  • C语言scandir函数获取文件夹内容的实现

    C语言scandir函数获取文件夹内容的实现

    scandir 函数用于列举指定目录下的文件列表,本文主要介绍了C语言scandir函数获取文件夹内容的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03

最新评论