【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)

简介: 【C++】深入解析C/C++内存管理:new与delete的使用及原理

【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)https://developer.aliyun.com/article/1617320


第一点:

int* p0 = (int*)malloc(sizeof(int));
  int* p1 = new int;

第二点:

int* p2 = new int[10];
  int* p3 = new int(10);
  int* p4 = new int[10]{ 1,2,3 };

第三点

struct ListNode
{
  ListNode* _next;
  int _val;
  ListNode(int val)
    :_val(val)
    ,_next(nullptr)
  {}
};
//创建不带哨兵位,同时如果是插入数据,new ListNode(3)即可
ListNode* CreateList(int n)
{
  ListNode head(-1);
  
  ListNode* tail = &head;
  int val;
  
  printf("请依次输入%d个节点的值:>", n);
  for (size_t i = 0; i < n; i++)
  {
    cin >> val;
    tail->_next = new ListNode(val);
    tail = tail->_next;
  }
  return head._next;
}

第四点:

void func()
{
  int n = 1;
  while (1)
  {
    int* p = new int[1024 * 1024*100];
    cout <<n<<"->"<< p << endl;
    ++n;
  }
}
int main()   
{
   try
  {
    func();
  }
  catch (const exception& e)
  {
    cout << e.what() << endl;
  }
    return 0;
}

这里try和catch就是捕捉异常,这一点到后面有涉及。以上种种都是new的优点,所以我们不推荐再使用malloc/free系列。

四、 new和delete原理及其两个全局函数的实现(operator new/operator delerte)

new和delete是用户进行动态内存申请和释放的操作符operator new和operator delete是系统提供的全局函数,new再底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间(operator new与operator delete不是对new和delete的重载)

int* p1 = (int*)operator new(10 * 4);
  //int* p1=new int(10*4)
  operator delete(p1);
  //delete(p1)

从代码中可以看出来,new/delete和operator new/operator delete效果上是相同的。那么直接使用new/delete就行,operator new/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)
    //通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果
    //malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施
    //就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。
    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/malloc与delete/free基本类似,不同的地方是new在申请空间失败时会抛异常,malloc会返回NULL

自定义类型:

new的原理:

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

delete的原理:

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

new T[N]的原理:

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

delete[]的原理:

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

通过汇编,深入立即其中

对于自定义类型转换指令只有两个核心动作调用全局函数及其构造或析构,而内置类型只有调用全局函数。

对此可得:

  • operator new是对malloc的封装,如果失败抛异常,实现new
  • operator newp[]封装operator new,最终还是malloc
  • operator delete对free的封装
  • operator delete[]封装operator delete

同时这里需要注意调用顺序上的问题


【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)https://developer.aliyun.com/article/1617323

相关文章
|
8月前
|
C语言 C++
c与c++的内存管理
再比如还有这样的分组: 这种分组是最正确的给出内存四个分区名字:栈区、堆区、全局区(俗话也叫静态变量区)、代码区(也叫代码段)(代码段又分很多种,比如常量区)当然也会看到别的定义如:两者都正确,记那个都选,我选择的是第一个。再比如还有这样的分组: 这种分组是最正确的答案分别是 C C C A A A A A D A B。
157 1
|
11月前
|
机器学习/深度学习 数据可视化 PyTorch
深入解析图神经网络注意力机制:数学原理与可视化实现
本文深入解析了图神经网络(GNNs)中自注意力机制的内部运作原理,通过可视化和数学推导揭示其工作机制。文章采用“位置-转移图”概念框架,并使用NumPy实现代码示例,逐步拆解自注意力层的计算过程。文中详细展示了从节点特征矩阵、邻接矩阵到生成注意力权重的具体步骤,并通过四个类(GAL1至GAL4)模拟了整个计算流程。最终,结合实际PyTorch Geometric库中的代码,对比分析了核心逻辑,为理解GNN自注意力机制提供了清晰的学习路径。
752 7
深入解析图神经网络注意力机制:数学原理与可视化实现
|
11月前
|
机器学习/深度学习 缓存 自然语言处理
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
Tiktokenizer 是一款现代分词工具,旨在高效、智能地将文本转换为机器可处理的离散单元(token)。它不仅超越了传统的空格分割和正则表达式匹配方法,还结合了上下文感知能力,适应复杂语言结构。Tiktokenizer 的核心特性包括自适应 token 分割、高效编码能力和出色的可扩展性,使其适用于从聊天机器人到大规模文本分析等多种应用场景。通过模块化设计,Tiktokenizer 确保了代码的可重用性和维护性,并在分词精度、处理效率和灵活性方面表现出色。此外,它支持多语言处理、表情符号识别和领域特定文本处理,能够应对各种复杂的文本输入需求。
1382 6
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
|
10月前
|
存储 监控 算法
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
215 4
|
11月前
|
传感器 人工智能 监控
反向寻车系统怎么做?基本原理与系统组成解析
本文通过反向寻车系统的核心组成部分与技术分析,阐述反向寻车系统的工作原理,适用于适用于商场停车场、医院停车场及火车站停车场等。如需获取智慧停车场反向寻车技术方案前往文章最下方获取,如有项目合作及技术交流欢迎私信作者。
901 2
|
11月前
|
存储 Linux C语言
C++/C的内存管理
本文主要讲解C++/C中的程序区域划分与内存管理方式。首先介绍程序区域,包括栈(存储局部变量等,向下增长)、堆(动态内存分配,向上分配)、数据段(存储静态和全局变量)及代码段(存放可执行代码)。接着探讨C++内存管理,new/delete操作符相比C语言的malloc/free更强大,支持对象构造与析构。还深入解析了new/delete的实现原理、定位new表达式以及二者与malloc/free的区别。最后附上一句鸡汤激励大家行动缓解焦虑。
|
11月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
11月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1098 29
|
11月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
467 4
|
11月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多
  • DNS