C++内存管理深度解析:自定义类型的new/delete与构造析构机制

# C++内存管理深度解析:自定义类型的new/delete与构造析构机制


## C++对象生命周期的内存管理全景


在C++中,对象的创建和销毁涉及两个独立但紧密相关的概念:内存分配与初始化、内存释放与清理。理解`new`和`delete`操作符如何与构造函数和析构函数交互,是掌握C++内存管理的关键。这些机制共同构成了对象生命周期的完整管理。


## new操作符的三步执行流程


### 内存分配与初始化分解


```cpp

#include

#include

#include


class ComplexObject {

private:

    int* data;

    size_t size;

    

public:

    // 构造函数

    ComplexObject(size_t s) : size(s) {

        std::cout << "构造函数被调用,大小: " << s << std::endl;

        data = new int[s];

        for (size_t i = 0; i < s; ++i) {

            data[i] = static_cast(i * 10);

        }

    }

    

    // 析构函数

    ~ComplexObject() {

        std::cout << "析构函数被调用,释放大小: " << size << std::endl;

        delete[] data;

    }

    

    void display() const {

        std::cout << "对象数据: ";

        for (size_t i = 0; i < (size < 5 ? size : 5); ++i) {

            std::cout << data[i] << " ";

        }

        std::cout << std::endl;

    }

};


// 手动模拟new操作符的三个步骤

void* operator new(size_t size) {

    std::cout << "全局operator new被调用,请求大小: " << size << " 字节" << std::endl;

    void* ptr = std::malloc(size);

    if (!ptr) {

        throw std::bad_alloc();

    }

    return ptr;

}


void operator delete(void* ptr) noexcept {

    std::cout << "全局operator delete被调用" << std::endl;

    std::free(ptr);

}


// 类特定的operator new和operator delete

class CustomAllocator {

private:

    static size_t allocation_count;

    static size_t total_allocated;

    

public:

    // 普通new

    static void* operator new(size_t size) {

        std::cout << "CustomAllocator::operator new, 大小: " << size << std::endl;

        allocation_count++;

        total_allocated += size;

        void* ptr = std::malloc(size);

        if (!ptr) throw std::bad_alloc();

        return ptr;

    }

    

    // 普通delete

    static void operator delete(void* ptr) noexcept {

        std::cout << "CustomAllocator::operator delete" << std::endl;

        std::free(ptr);

    }

    

    // 数组new

    static void* operator new[](size_t size) {

        std::cout << "CustomAllocator::operator new[], 大小: " << size << std::endl;

        allocation_count++;

        total_allocated += size;

        void* ptr = std::malloc(size);

        if (!ptr) throw std::bad_alloc();

        return ptr;

    }

    

    // 数组delete

    static void operator delete[](void* ptr) noexcept {

        std::cout << "CustomAllocator::operator delete[]" << std::endl;

        std::free(ptr);

    }

    

    // 放置new

    static void* operator new(size_t size, void* ptr) noexcept {

        std::cout << "CustomAllocator::placement new, 使用预分配内存" << std::endl;

        return ptr;

    }

    

    // 放置delete(通常为空)

    static void operator delete(void* ptr, void* place) noexcept {

        std::cout << "CustomAllocator::placement delete" << std::endl;

        // 不释放内存,因为内存不是由此分配的

    }

    

    static void print_stats() {

        std::cout << "分配统计: 次数=" << allocation_count 

                  << ", 总量=" << total_allocated << " 字节" << std::endl;

    }

};


size_t CustomAllocator::allocation_count = 0;

size_t CustomAllocator::total_allocated = 0;

```


## 构造与析构的调用时机


### 构造函数调用链


```cpp

#include


class BaseClass {

public:

    BaseClass() {

        std::cout << "BaseClass构造函数" << std::endl;

    }

    

    virtual ~BaseClass() {

        std::cout << "BaseClass析构函数" << std::endl;

    }

};


class DerivedClass : public BaseClass {

private:

    int* resource;

    

public:

    DerivedClass() : BaseClass() {

        std::cout << "DerivedClass构造函数开始" << std::endl;

        resource = new int[100];

        std::cout << "DerivedClass构造函数结束" << std::endl;

    }

    

    ~DerivedClass() override {

        std::cout << "DerivedClass析构函数开始" << std::endl;

        delete[] resource;

        std::cout << "DerivedClass析构函数结束" << std::endl;

    }

};


class MemberClass {

public:

    MemberClass() {

        std::cout << "MemberClass构造函数" << std::endl;

    }

    

    ~MemberClass() {

        std::cout << "MemberClass析构函数" << std::endl;

    }

};


class ContainerClass {

private:

    MemberClass member;

    int* dynamic_array;

    

public:

    ContainerClass() : member() {

        std::cout << "ContainerClass构造函数开始" << std::endl;

        dynamic_array = new int[50];

        std::cout << "ContainerClass构造函数结束" << std::endl;

    }

    

    ~ContainerClass() {

        std::cout << "ContainerClass析构函数开始" << std::endl;

        delete[] dynamic_array;

        std::cout << "ContainerClass析构函数结束" << std::endl;

    }

};

```


### 构造与析构顺序验证


```cpp

void demonstrate_construction_order() {

    std::cout << "\n=== 对象构造顺序演示 ===" << std::endl;

    

    // 1. 栈对象 - 自动构造和析构

    {

        std::cout << "\n创建栈对象:" << std::endl;

        ComplexObject stack_obj(10);

        stack_obj.display();

        std::cout << "离开作用域,栈对象将自动析构" << std::endl;

    }

    

    // 2. 堆对象 - 手动管理

    std::cout << "\n创建堆对象:" << std::endl;

    ComplexObject* heap_obj = new ComplexObject(20);

    heap_obj->display();

    std::cout << "手动删除堆对象" << std::endl;

    delete heap_obj;

    

    // 3. 派生类对象

    std::cout << "\n创建派生类对象:" << std::endl;

    DerivedClass* derived = new DerivedClass();

    std::cout << "删除派生类对象" << std::endl;

    delete derived;

    

    // 4. 包含成员的对象

    std::cout << "\n创建包含成员的对象:" << std::endl;

    ContainerClass* container = new ContainerClass();

    std::cout << "删除包含成员的对象" << std::endl;

    delete container;

}

```


## 自定义分配器的实现


### 内存池分配器


```cpp

#include

#include

#include

#include


class MemoryPool {

private:

    struct Block {

        Block* next;

    };

    

    Block* free_list;

    size_t block_size;

    size_t pool_size;

    std::vector memory_chunks;

    

public:

    MemoryPool(size_t block_sz, size_t num_blocks) 

        : free_list(nullptr), block_size(block_sz), pool_size(block_sz * num_blocks) {

        

        // 分配内存块

        char* chunk = new char[pool_size];

        memory_chunks.push_back(chunk);

        

        // 初始化空闲链表

        for (size_t i = 0; i < num_blocks; ++i) {

            Block* block = reinterpret_cast(chunk + i * block_size);

            block->next = free_list;

            free_list = block;

        }

        

        std::cout << "内存池创建: 块大小=" << block_size 

                  << ", 总大小=" << pool_size << std::endl;

    }

    

    ~MemoryPool() {

        std::cout << "销毁内存池" << std::endl;

        for (auto chunk : memory_chunks) {

            delete[] chunk;

        }

    }

    

    void* allocate() {

        if (!free_list) {

            // 扩展内存池

            expand_pool();

        }

        

        Block* block = free_list;

        free_list = free_list->next;

        

        std::cout << "从内存池分配: " << block << std::endl;

        return static_cast(block);

    }

    

    void deallocate(void* ptr) {

        if (!ptr) return;

        

        Block* block = static_cast(ptr);

        block->next = free_list;

        free_list = block;

        

        std::cout << "返回到内存池: " << ptr << std::endl;

    }

    

private:

    void expand_pool() {

        std::cout << "扩展内存池" << std::endl;

        char* chunk = new char[pool_size];

        memory_chunks.push_back(chunk);

        

        size_t num_blocks = pool_size / block_size;

        for (size_t i = 0; i < num_blocks; ++i) {

            Block* block = reinterpret_cast(chunk + i * block_size);

            block->next = free_list;

            free_list = block;

        }

    }

};


// 使用内存池的自定义类型

class PoolAllocated {

private:

    static MemoryPool pool;

    int value;

    

public:

    static void initialize_pool(size_t num_objects) {

        pool = MemoryPool(sizeof(PoolAllocated), num_objects);

    }

    

    static void* operator new(size_t size) {

        if (size != sizeof(PoolAllocated)) {

            return ::operator new(size);

        }

        return pool.allocate();

    }

    

    static void operator delete(void* ptr) {

        if (!ptr) return;

        pool.deallocate(ptr);

    }

    

    PoolAllocated(int v) : value(v) {

        std::cout << "PoolAllocated构造: " << value << " at " << this << std::endl;

    }

    

    ~PoolAllocated() {

        std::cout << "PoolAllocated析构: " << value << " at " << this << std::endl;

    }

    

    void display() const {

        std::cout << "值: " << value << std::endl;

    }

};


MemoryPool PoolAllocated::pool(sizeof(PoolAllocated), 0);

```


### 对齐内存分配器


```cpp

#include

#include


class AlignedAllocator {

public:

    // 对齐的operator new

    static void* operator new(size_t size, size_t alignment) {

        std::cout << "对齐分配请求: 大小=" << size 

                  << ", 对齐=" << alignment << std::endl;

        

        // 计算需要的内存大小

        size_t actual_size = size + alignment - 1 + sizeof(void*);

        void* original_ptr = std::malloc(actual_size);

        

        if (!original_ptr) {

            throw std::bad_alloc();

        }

        

        // 计算对齐的地址

        void* aligned_ptr = reinterpret_cast(

            (reinterpret_cast(original_ptr) + sizeof(void*) + alignment - 1) 

            & ~(alignment - 1));

        

        // 在aligned_ptr之前存储original_ptr用于释放

        *(reinterpret_cast(aligned_ptr) - 1) = original_ptr;

        

        std::cout << "原始指针: " << original_ptr 

                  << ", 对齐指针: " << aligned_ptr << std::endl;

        return aligned_ptr;

    }

    

    // 对应的operator delete

    static void operator delete(void* aligned_ptr) noexcept {

        if (!aligned_ptr) return;

        

        // 获取原始指针

        void* original_ptr = *(reinterpret_cast(aligned_ptr) - 1);

        std::cout << "释放对齐内存: 对齐指针=" << aligned_ptr 

                  << ", 原始指针=" << original_ptr << std::endl;

        

        std::free(original_ptr);

    }

};


// 使用对齐分配的自定义类型

class AlignedData {

private:

    alignas(64) double matrix[8][8];  // 64字节对齐的矩阵

    int id;

    

public:

    static void* operator new(size_t size) {

        // 请求64字节对齐

        return AlignedAllocator::operator new(size, 64);

    }

    

    static void operator delete(void* ptr) {

        AlignedAllocator::operator delete(ptr);

    }

    

    AlignedData(int i) : id(i) {

        std::cout << "AlignedData构造: ID=" << id 

                  << ", 地址=" << this 

                  << ", 对齐=" << alignof(*this) << std::endl;

        

        // 初始化矩阵

        for (int i = 0; i < 8; ++i) {

            for (int j = 0; j < 8; ++j) {

                matrix[i][j] = static_cast(i * 8 + j);

            }

        }

    }

    

    ~AlignedData() {

        std::cout << "AlignedData析构: ID=" << id << std::endl;

<"6d.yunruiwater.cn"><"0g.sxyicheng.cn"><"7n.jsnjz.cn">

    }

    

    void verify_alignment() const {

        uintptr_t addr = reinterpret_cast(this);

        if (addr % 64 == 0) {

            std::cout << "对象正确对齐到64字节边界" << std::endl;

        } else {

            std::cout << "对象未对齐到64字节边界" << std::endl;

        }

    }

};

```


## 异常安全与资源管理


### RAII资源管理类


```cpp

#include

#include


template

class ScopedArray {

private:

    T* ptr;

    

    // 禁止拷贝

    ScopedArray(const ScopedArray&) = delete;

    ScopedArray& operator=(const ScopedArray&) = delete;

    

public:

    // 显式构造函数

    explicit ScopedArray(size_t size) {

        std::cout << "ScopedArray分配: " << size << " 个元素" << std::endl;

        ptr = new T[size];

    }

    

    // 移动构造函数

    ScopedArray(ScopedArray&& other) noexcept : ptr(other.ptr) {

        other.ptr = nullptr;

        std::cout << "ScopedArray移动构造" << std::endl;

    }

    

    // 移动赋值运算符

    ScopedArray& operator=(ScopedArray&& other) noexcept {

        if (this != &other) {

            delete[] ptr;

            ptr = other.ptr;

            other.ptr = nullptr;

            std::cout << "ScopedArray移动赋值" << std::endl;

        }

        return *this;

    }

    

    // 析构函数

    ~ScopedArray() {

        std::cout << "ScopedArray析构" << std::endl;

        delete[] ptr;

    }

    

    // 访问元素

    T& operator[](size_t index) {

        return ptr[index];

    }

    

    const T& operator[](size_t index) const {

        return ptr[index];

    }

    

    // 获取原始指针

    T* get() { return ptr; }

    const T* get() const { return ptr; }

};


// 异常安全的对象构造

class ExceptionSafeObject {

private:

    ScopedArray data;

    std::unique_ptr more_data;

    

public:

    // 构造函数模板,提供异常安全保证

    ExceptionSafeObject(size_t size1, size_t size2) 

        : data(size1),  // 如果失败,data会正确清理

          more_data(std::make_unique(size2)) {  // 如果失败,已分配的资源会被清理

        

        std::cout << "ExceptionSafeObject构造函数开始" << std::endl;

        

        // 可能抛出异常的操作

        if (size1 == 0) {

            throw std::invalid_argument("size1不能为零");

        }

        

        // 初始化数据

        for (size_t i = 0; i < size1; ++i) {

            data[i] = static_cast(i * 2);

        }

        

        std::cout << "ExceptionSafeObject构造函数完成" << std::endl;

    }

    

    ~ExceptionSafeObject() {

        std::cout << "ExceptionSafeObject析构函数" << std::endl;

    }

    

    void display() const {

        std::cout << "异常安全对象数据: ";

        for (size_t i = 0; i < 5 && i < 10; ++i) {

            std::cout << data[i] << " ";

        }

        std::cout << std::endl;

    }

};

```


## 数组new/delete的特殊处理


```cpp

#include


class ArrayObject {

private:

    static int object_count;

    int id;

    

public:

    ArrayObject() : id(++object_count) {

        std::cout << "ArrayObject构造 #" << id << std::endl;

    }

    

    ~ArrayObject() {

        std::cout << "ArrayObject析构 #" << id << std::endl;

    }

    

    // 自定义数组new

    static void* operator new[](size_t size) {

        std::cout << "ArrayObject::operator new[] 请求大小: " << size << std::endl;

        

        // 为数组大小信息分配额外空间

        size_t actual_size = size + sizeof(size_t);

        void* ptr = ::operator new(actual_size);

        

        // 存储元素数量

        size_t* size_ptr = static_cast(ptr);

        *size_ptr = (size - sizeof(ArrayObject)) / sizeof(ArrayObject) + 1;

        

        std::cout << "分配了 " << *size_ptr << " 个对象的数组" << std::endl;

        

        // 返回第一个对象的位置

        return static_cast(ptr) + sizeof(size_t);

    }

    

    // 自定义数组delete

    static void operator delete[](void* ptr) noexcept {

        if (!ptr) return;

        

        // 获取数组大小信息的位置

        void* original_ptr = static_cast(ptr) - sizeof(size_t);

        size_t* size_ptr = static_cast(original_ptr);

        

        std::cout << "释放 " << *size_ptr << " 个对象的数组" << std::endl;

        

        ::operator delete(original_ptr);

    }

};


int ArrayObject::object_count = 0;


void demonstrate_array_new_delete() {

    std::cout << "\n=== 数组new/delete演示 ===" << std::endl;

    

    // 创建对象数组

    ArrayObject* arr = new ArrayObject[5];

    

    // 必须使用对应的delete[]

    delete[] arr;

    

    std::cout << "\n=== 单个对象误用数组delete ===" << std::endl;

    ArrayObject* single = new ArrayObject;

    

    // 错误:对单个对象使用delete[]

    // delete[] single;  // 未定义行为!

    

    delete single;  // 正确

}

```


## 放置new的高级用法


```cpp

#include

#include


class PlacementDemo {

private:

    int value;

    

public:

    PlacementDemo(int v) : value(v) {

        std::cout << "PlacementDemo构造: " << value 

                  << " at " << this << std::endl;

    }

    

    ~PlacementDemo() {

        std::cout << "PlacementDemo析构: " << value 

                  << " at " << this << std::endl;

    }

    

    void show() const {

        std::cout << "值: " << value << std::endl;

    }

    

    // 自定义放置new,带额外参数

    static void* operator new(size_t size, void* ptr, const char* location) {

        std::cout << "自定义放置new在: " << location << std::endl;

        return ::operator new(size, ptr);  // 调用标准放置new

    }

    

    // 对应的放置delete

    static void operator delete(void* ptr, void* place, const char* location) {

        std::cout << "自定义放置delete从: " << location << std::endl;

        // 通常什么都不做

    }

};


void demonstrate_placement_new() {

    std::cout << "\n=== 放置new演示 ===" << std::endl;

    

    // 预分配内存

    alignas(PlacementDemo) char buffer[sizeof(PlacementDemo) * 3];

    

    // 在预分配内存中构造对象

    PlacementDemo* p1 = new(buffer) PlacementDemo(100);

    p1->show();

    

    // 在缓冲区的其他位置构造第二个对象

    PlacementDemo* p2 = new(buffer + sizeof(PlacementDemo)) PlacementDemo(200);

    p2->show();

    

    // 手动调用析构函数

    std::cout << "手动调用析构函数:" << std::endl;

    p1->~PlacementDemo();

    p2->~PlacementDemo();

    

    // 使用自定义放置new

    std::cout << "\n使用自定义放置new:" << std::endl;

    PlacementDemo* p3 = new(buffer, "自定义位置") PlacementDemo(300);

    p3->show();

    

    // 调用对应的删除函数

    ::operator delete(p3, buffer, "自定义位置");

}

```


## 调试与诊断工具


```cpp

#include

#include

#include


class MemoryTracker {

private:

    static std::map> allocations;

<"1r.csxthr.com"><"4t.zhaiLimao.com"><"8v.yunruiwater.cn">

    static std::mutex tracker_mutex;

    static size_t total_allocated;

    

public:

    static void* track_allocation(size_t size, const char* type_name) {

        void* ptr = std::malloc(size);

        if (!ptr) throw std::bad_alloc();

        

        std::lock_guard lock(tracker_mutex);

        allocations[ptr] = {size, type_name};

        total_allocated += size;

        

        std::cout << "追踪分配: " << ptr << " 大小: " << size 

                  << " 类型: " << type_name << std::endl;

        return ptr;

    }

    

    static void track_deallocation(void* ptr) {

        if (!ptr) return;

        

        std::lock_guard lock(tracker_mutex);

        auto it = allocations.find(ptr);

        if (it != allocations.end()) {

            total_allocated -= it->second.first;

            std::cout << "追踪释放: " << ptr << " 大小: " << it->second.first 

                      << " 类型: " << it->second.second << std::endl;

            allocations.erase(it);

        } else {

            std::cout << "警告: 释放未追踪的指针: " << ptr << std::endl;

        }

        

        std::free(ptr);

    }

    

    static void print_memory_report() {

        std::lock_guard lock(tracker_mutex);

        std::cout << "\n=== 内存追踪报告 ===" << std::endl;

        std::cout << "总分配内存: " << total_allocated << " 字节" << std::endl;

        std::cout << "活动分配数: " << allocations.size() << std::endl;

        

        for (const auto& [ptr, info] : allocations) {

            std::cout << "  " << ptr << ": " << info.first 

                      << " 字节 (" << info.second << ")" << std::endl;

        }

    }

};


std::map> MemoryTracker::allocations;

std::mutex MemoryTracker::tracker_mutex;

size_t MemoryTracker::total_allocated = 0;


// 使用内存追踪的自定义类型

class TrackedObject {

private:

    int data[100];

    

public:

    static void* operator new(size_t size) {

        return MemoryTracker::track_allocation(size, "TrackedObject");

    }

    

    static void operator delete(void* ptr) {

        MemoryTracker::track_deallocation(ptr);

    }

    

    static void* operator new[](size_t size) {

        return MemoryTracker::track_allocation(size, "TrackedObject[]");

    }

    

    static void operator delete[](void* ptr) {

        MemoryTracker::track_deallocation(ptr);

    }

    

    TrackedObject() {

        std::cout << "TrackedObject构造 at " << this << std::endl;

    }

    

    ~TrackedObject() {

        std::cout << "TrackedObject析构 at " << this << std::endl;

    }

};


void demonstrate_memory_tracking() {

    std::cout << "\n=== 内存追踪演示 ===" << std::endl;

    

    TrackedObject* obj1 = new TrackedObject;

    TrackedObject* obj2 = new TrackedObject;

    TrackedObject* arr = new TrackedObject[3];

    

    delete obj1;

    delete[] arr;

    

    // 注意:obj2 故意不删除,以展示内存泄漏检测

    MemoryTracker::print_memory_report();

    

    delete obj2;  // 最后删除

}

```


## 最佳实践总结


通过深入了解自定义类型的new/delete操作符与构造/析构函数的交互机制,开发者可以更好地控制对象生命周期,实现高效、安全的内存管理。关键要点包括:


1. **明确资源所有权**:确保每个资源都有明确的所有者和生命周期

2. **遵循RAII原则**:资源获取即初始化,利用构造函数和析构函数管理资源

3. **异常安全保证**:确保在异常发生时资源能够正确释放

4. **使用智能指针**:优先使用`std::unique_ptr`和`std::shared_ptr`

5. **自定义分配器谨慎使用**:只在确实需要优化性能时使用


正确的内存管理不仅能避免内存泄漏和未定义行为,还能提升程序性能和可维护性。通过掌握这些底层机制,开发者能够编写出更加健壮和高效的C++代码。


请使用浏览器的分享功能分享到微信等