深入探讨 C++ 的 new 和 delete:内存分配与释放机制

1. new 和 new[] 的工作原理

简单类型:

  • 使用 operator new 分配内存。
  • 如果是 new[](数组),计算总大小后一起分配。

复杂类型(类对象等):

  • 先调用 operator new 分配内存。
  • 然后在分配的内存上调用构造函数。
  • 对于 new[](对象数组),先调用 operator new[] 分配内存,并在内存区域前部保存数组大小,然后调用构造函数。

示例及注释:

#include <iostream>
#include <new>  // For std::bad_alloc

class MyClass {
public:
    MyClass() { std::cout << "Constructor called" << std::endl; }
    ~MyClass() { std::cout << "Destructor called" << std::endl; }
    void* operator new(size_t size) {
        std::cout << "operator new called" << std::endl;
        return ::operator new(size);
    }
    void operator delete(void* ptr) {
        std::cout << "operator delete called" << std::endl;
        ::operator delete(ptr);
    }
    void* operator new[](size_t size) {
        std::cout << "operator new[] called" << std::endl;
        return ::operator new(size);
    }
    void operator delete[](void* ptr) {
        std::cout << "operator delete[] called" << std::endl;
        ::operator delete(ptr);
    }
};

int main() {
    // 单个对象
    MyClass* obj = new MyClass();  // 调用 operator new 和构造函数
    delete obj;  // 调用析构函数和 operator delete

    // 对象数组
    MyClass* array = new MyClass[3];  // 调用 operator new[] 和每个对象的构造函数
    delete[] array;  // 调用每个对象的析构函数和 operator delete[]

    return 0;
}
2. delete 和 delete[] 的工作原理

简单类型:

  • 直接调用 free 函数。

复杂类型(类对象等):

  • 调用析构函数释放资源。
  • 直接调用 operator delete 释放内存。
  • 对于 delete[],从内存区域读取数组大小,再依次调用析构函数后,再调用 operator delete[] 释放整体内存。

示例及注释:

#include <iostream>
#include <cstdlib> // For malloc and free

class Complex {
private:
    int* data;
public:
    Complex() {
        data = new int[10];  // Allocate resource
        std::cout << "Complex Constructor called" << std::endl;
    }
    ~Complex() {
        delete[] data;  // Release resource
        std::cout << "Complex Destructor called" << std::endl;
    }
};

int main() {
    // 简单类型
    int* p = static_cast<int*>(std::malloc(sizeof(int)));
    *p = 10;
    std::free(p);  // 释放内存,不涉及构造和析构函数

    // 复杂类型
    Complex* obj = new Complex();  // 调用 operator new 和构造函数
    delete obj;  // 调用析构函数和 operator delete

    // 复杂类型数组
    Complex* array = new Complex[3];  // 调用 operator new[] 和每个对象的构造函数
    delete[] array;  // 调用每个对象的析构函数和 operator delete[]

    return 0;
}
3. 内存布局和 delete[] 释放内存的工作机制
  • new 和 new[] 在分配内存时,如果是数组,会在分配的内存块前部预留额外的空间存储数组大小。

示例及注释:

#include <iostream>
#include <cstdlib>  // for malloc and free

void* operator new[](size_t size) {
    void* ptr = std::malloc(size + sizeof(size_t));
    if (!ptr) throw std::bad_alloc();
    *static_cast<size_t*>(ptr) = size;  // Store size at the start
    return static_cast<void*>(static_cast<char*>(ptr) + sizeof(size_t));
}

void operator delete[](void* ptr) noexcept {
    if (!ptr) return;
    void* realPtr = static_cast<void*>(static_cast<char*>(ptr) - sizeof(size_t));
    size_t size = *static_cast<size_t*>(realPtr);
    std::free(realPtr);
}

class MyClass {
public:
    int x;
    ~MyClass() { std::cout << "MyClass Destructor called" << std::endl; }
};

int main() {
    MyClass* arr = new MyClass[3];  // operator new[] called
    delete[] arr;  // Calls destructors then operator delete[]

    return 0;
}

结论

上面的代码示例和注释详细说明了 new 与 delete 的工作原理,特别是对于 C++ 中复杂类型和数组的内存管理方式。通过这些知识,可以深入理解 C++ 动态内存管理机制,提高编程的可靠性和效率。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值