详析new/delete内存分配与释放的内部工作流程

本文详细剖析了C++中new和delete操作符用于内存分配和释放的工作原理,包括内存泄漏问题、内存分配过程、以及array new的特性。通过示例代码解释了new如何调用构造函数,delete如何调用析构函数,并探讨了内存区块的对齐方式和cookie的作用。同时,文章强调了在使用array new分配数组时,必须配合array delete释放,以避免特定类型的内存泄漏问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 示例类

提供一个精简版的复数类和一个精简版的字符串类用来演示。
示例类中函数均取自C++标准库。

复数类:

#include <iostream>
#include <thread>
#include <map>
using namespace std;
//复数类
class Complex
{
   
public:
    /*
    提供默认构造函数,采用初始化列表方式,构造函数执行有两个执行阶段
    1. 初始化阶段 2.函数体内部赋值阶段(按执行时间排序)
    在给成员变量进行赋值时最好采用初始化列表的方式,而不是采用构造函数体内部赋值方式
    Complex(double re = 0, double im = 0) 
    {
        m_re = re; m_im = im; //这样的方式当然也可行,但是浪费了一次初始化值的机会。
    };
    如果采用构造函数体内部方式相当于错过了初始化阶段。
    */
    Complex(double re = 0, double im = 0) :m_re(re), m_im(im) {
   };
    Complex& operator+=(const Complex& r) 
    {
   
        m_re += r.m_re;
        m_im += r.m_im;
        return *this;
    }
    /*
    * 对于函数体内部不需要更改数据的函数,最好在后面加上const。
    * 例如const Complex c这种使用场景,如果函数real()、imag()不加const
    * 编译器在看到const Complex c时一定认为c是不会改变数据的,但是调用real()/imag()函数时没有const
    * 编译器又以为要修改数据,这个是不好的做法。
    */
    double real() const {
    return m_re; }
    double imag() const {
    return m_im; }
//对于所有的数据,最好采用private保护起来,如果外部需要访问数据提供外部接口即可。
private:
    double m_re;
    double m_im;
};

/*
对于重载的操作符,可以采用成员函数的方式也可以采用全局函数的方式。
此处采用全局函数的考量是因为如果采用成员函数,那么只能计算Complex类之间相加。
但实际上复数可以和实数加,实数并不属于Complex类,所以如果设计为成员函数operator+,那么功能会被有所限制
*/
Complex operator+(const Complex& x, const Complex& y)//复数+复数
{
   
    return Complex(x.real(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值