现代 C++ 编程实战
吴咏炜
前 Intel 资深软件架构师
34199 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 51 讲
加餐 (1讲)
现代 C++ 编程实战
15
15
1.0x
00:00/00:00
登录|注册

31|new和delete背后:分配函数和释放函数

debug_new.cpp
operator delete(void*, void*)
operator new(size_t, void*)
new(std::nothrow) Obj
与标准的分配和释放函数接口一致
平台相关,如 Linux 上的链接优先级
operator delete 不抛出异常 (noexcept)
operator new 抛出 std::bad_alloc
转到 C 标准库的 mallocfree
operator delete[]
operator delete
operator new[]
operator new
[8] 设计和实现静态内存池
[7] debug_new.cpp
[6] aligned_memory.cpp
[5] Microsoft - <cstdlib>
[4] cppreference.com - operator delete, operator delete[]
[3] cppreference.com - operator new, operator new[]
[2] cppreference.com - new expression
[1] 内存泄漏检测器
new Obj[n]operator new[] 返回的指针关系
new Objoperator new 返回的指针关系
分配函数和释放函数的作用和定制
现代 C++ 中的局限性
仅对某个类替换
内存泄漏检测器
实现内存池
内存跟踪和排错
适配特定平台或环境
对齐保证
std::align_val_t
对齐释放函数
对齐分配函数
无异常编程场景
接口要求
实现机制
用户提供的 operator newoperator delete
异常处理
默认实现
释放函数 (deallocation function)
分配函数 (allocation function)
参考资料
课后思考
内容小结
类特定的分配和释放函数
替换分配和释放函数
内存对齐的分配和释放函数 (C++17)
布置分配和释放函数 (placement new/delete)
定制分配和释放行为
分配和释放函数的默认行为
基本概念
new 和 delete 背后:分配函数和释放函数

该思维导图由 AI 生成,仅供参考

你好,我是吴咏炜。
有一个我之前没讲、但挺有意思的话题是 newdelete 行为的定制。这件事情我很久很久以前就做过 [1],没往专栏里写的最主要原因是,这实际是 C++98 就有的高级技巧,不属于现代 C++。不过,在目前续写的内容里,我就不再拘泥必须新了,既然这是 C++ 里现在仍然需要的技巧,那就还是介绍一下。何况,这部分在现代 C++ 里还是有点新内容的。

最常用的分配和释放函数

第 1 讲,我提到过,当我们使用 newdelete 来创建和销毁对象时,实际发生的事情还是比较多的(如果忘了的话,可以去复习一下)。其中,分配内存和释放内存的操作是通过 operator newoperator delete 函数完成的。在最简单的 newdelete 形式里,我们使用的是以下两个函数:
void* operator new(size_t size);
void operator delete(void* ptr) noexcept;
operator newoperator delete 函数通常就被称为分配函数(allocation function)和释放函数(deallocation function)。
需要注意 operator new 是可能抛出异常的,而 operator delete 则不会抛出异常,被标为 noexcept。这和我们通常不允许在析构函数中抛出异常是完全一致的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了C++中的内存分配和释放机制,着重介绍了`new`和`delete`操作背后涉及的分配函数和释放函数。文章首先讨论了`operator new`和`operator delete`函数的默认实现,以及针对数组形式的分配和释放函数。接着,文章详细探讨了内存对齐的分配和释放函数,在C++17之前的问题和C++17引入的解决方式。此外,还介绍了替换分配和释放函数的重要性,以及类特定的分配和释放函数的应用场景。最后,文章指出了类特定的分配和释放函数在现代C++中的局限性,并展望了对容器的分配器参数的讨论。总的来说,本文深入剖析了C++内存管理的技术细节,为读者提供了全面的了解和思考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 C++ 编程实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(7)

  • 最新
  • 精选
  • 罗 乾 林
    前一个相同,后一个不同(除开POD)。数组会在头部存放对象的大小,这样才能依次找到数组中的每个对象地址,调用析构函数

    作者回复: 言简意赅👍。

    2022-02-24
    5
    10
  • tang_ming_wu
    new Obj返回的是调用构造函数初始化完成的对象指针; operator new 返回的只是一块足够容纳这个对象大小的空白的内存空间。 不知道我的理解准不准确。

    作者回复: 是。 但这不是我问的问题。我问的是这两个指针的值是不是相同。

    2022-02-24
    1
  • 记事本
    看不懂 怎么整?

    作者回复: 反复多看几遍,加看文末的参考资料和里面的代码。这一讲讲解原理,本身没有独立的示例代码。[7] 里有全局替换内存函数的例子。

    2022-10-18归属地:上海
  • 禾桃
    麻烦问下, new Obj 对应的表达式是 auto ptr = new Obj; operator new对应的表达式是?

    作者回复: 部分就是我问的问题了🤭。new 是会去调用 operator new(size_t) 来分配内存的。

    2022-04-22
  • 高伸
    吴老师有个问题想请教下,在查阅gcc4.9中stl源码时,发现allocator申请内存时直接调用::operator new,为什么没有如以前一样采用二级缓存pool_allocator的方式呢

    作者回复: 看下一讲“容器里的内存管理:分配器”吧。

    2022-03-29
  • 怪兽
    在"不分配内存的布置分配和释放函数"小节里,老师有提到"另外注意,跟大部分其他分配函数和释放函数不同,这个函数是不能被用户提供的版本替换的"。这里说的"这个函数"是指这两个函数吗? inline void* operator new(size_t, void* ptr) noexcept { return ptr; } inline void operator delete(void*, void*) noexcept {}

    作者回复: 嗯嗯,应该写“这些函数”。😂

    2022-02-24
  • 农民园丁
    居然还有31,太值了!

    作者回复: 😝

    2022-02-24
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部