地心探索 · 内存分配控制

在 C++ 的世界里,内存管理是一门深奥的艺术。大多数时候,我们使用 newdelete,或者更好的智能指针。但当你需要极致的性能,或者需要控制内存的每一个字节时,就需要深入到内存分配的底层。

让我们开始这场地心探索之旅。


new 和 delete 的本质

当你写 new int(42) 时,实际发生了两件事:

  1. 调用 operator new 分配内存

  2. 在分配的内存上调用构造函数

#include <iostream>
#include <new>

class Widget
{
public:
    int value;
    Widget(int v) : value(v) { std::cout << "Constructed: " << value << std::endl; }
    ~Widget() { std::cout << "Destructed: " << value << std::endl; }
};

int main()
{
    // 这两种写法是等价的:
    Widget* w1 = new Widget(42);
    
    // 等价于:
    void* memory = operator new(sizeof(Widget));  // 分配内存
    Widget* w2 = new (memory) Widget(42);         // 原位构造
    
    // 销毁时
    delete w1;
    
    // 等价于:
    w2->~Widget();              // 调用析构函数
    operator delete(memory);    // 释放内存
    
    return 0;
}

重载 operator new 和 operator delete

你可以为类或全局重载这些运算符:


placement new:在指定位置构造对象

有时候你想在已分配的内存上构造对象:

placement new 的常见用途


allocator:标准分配器

C++ 标准库提供了 std::allocator,它是容器默认使用的分配器:


自定义分配器

你可以为标准容器提供自定义分配器:


内存池实现

高性能应用常用内存池来避免频繁的堆分配:


内存对齐

现代 CPU 对内存对齐有要求,访问对齐的内存更快:


std::aligned_storage 和 std::aligned_union

用于创建正确对齐的存储:


pmr:多态内存资源(C++17)

C++17 引入了多态内存资源,可以在运行时切换分配策略:


内存泄漏检测

简单的内存泄漏追踪器:


总结

技术
用途

operator new/delete 重载

自定义分配策略

placement new

在指定位置构造对象

std::allocator

标准分配器接口

自定义分配器

为容器提供特殊分配策略

内存池

减少分配开销

alignas

控制内存对齐

std::pmr

多态内存资源

掌握这些技术,你就能像探索地心一样,深入到 C++ 内存管理的最底层,实现真正的性能优化。

Last updated