[Effective C++]条款16:成对使用new和delete时要采取相同形式

C++中,new和delete时用于动态内存管理的操作符.他们的底层实现和编译器处理涉及到内存分配、对象构造和析构等.

1、new和delete底层实现原理

1.1、new的底层实现

  • 内存分配: new操作符会调用operator new函数来分配内存.operator new是C++标准库提供的全局函数,通常底层会调用malloc或其他内存分配器.
  • 对象构造: 在分配内存后,new会调用对象的构造函数来初始化对象.
  • 编译器处理: 编译器会生成代码,确保在分配内存后调用构造函数.

1.2、delete的底层实现

  • 对象析构: delete操作符会先调用对象的析构函数来销毁对象.
  • 内存释放: 在析构完成后,delete会调用operator delete函数来释放内存. Operator delete通常底层会调用free函数
  • 编译器处理: 编译器会生成代码,确保在调用了析构函数后释放内存.

2、new和delete操作符的使用

2.1、单个对象

  • 使用new创建单个对象,使用delete释放单个对象
int* p = new int(10);  // 分配一个int对象,并初始化为10
delete p; // 释放单个对象

2.2、数组

  • 使用new[] 创建数组,使用delete[] 释放数组
int* arr = new int[10];  // 创建一个包含10各int元素的数组
delete[] arr;  // 释放数组

3、错误使用

3.1、使用delete释放数组

  • 如果使用delete释放数组,只会调用第一个元素的析构函数,其余元素不会被正确析构,导致内存泄漏或未定义行为
int* arr = new int[10];
delete arr;  // 错误:应该使用 delete[]

3.2、使用delete[] 释放单个对象

  • 如果使用delete[]释放单个对象,会导致未定义行为,因为delete[] 会尝试释放多个对象的内存
int* p = new int(10);
delete[] p;  // 错误:应该使用 delete

4、示例代码

  • 正确使用new和delete是避免内存泄漏和未定义行为的关键.
  • 实际开发中,建议优先使用智能指针来管理动态内存,减少手动管理内存的风险.
#include <iostream>

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

int main() {
    // 正确使用:单个对象
    MyClass* obj = new MyClass();
    delete obj;  // 正确

    // 正确使用:数组
    MyClass* arr = new MyClass[3];
    delete[] arr;  // 正确

    // 错误使用:delete 释放数组
    MyClass* arr2 = new MyClass[3];
    // delete arr2;  // 错误:会导致内存泄漏和未定义行为

    // 错误使用:delete[] 释放单个对象
    MyClass* obj2 = new MyClass();
    // delete[] obj2;  // 错误:会导致未定义行为

    return 0;
}

思维导图笔记:

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值