C++ new,delete原理分析

        C++编译器隐藏了代码实现,没有那么透明,javajdk开源,比较透明,大部分实现都可以看到,Qt也是开源,具体实现我们也可以看到。

         new,delete是C++动态内存分配与释放的关键字也是一种特殊的运算符,很多书籍,博客都说底层是用operator new和operator delete实现的。主要涉及到了如下四组函数: 

  void* operator new(size_t size);
  void* operator new[](size_t size);
  void operator delete(void *p);
  void operator delete[](void *p);

        那么他们究竟是怎么知道的呢,书籍作者可能和C++委员会成员,了解C++的实现,我们也可以从现有的代码,资料中了解一二。

        下面, 我们从一个简单的程序开始来剖析C++的new与delete机制.

#include <iostream>

class A 
{
public:
	A(int cnt)
	{
		m_Cnt = cnt;
	}

	~A()
	{

	}

private:
	int m_Cnt;
};

int main()
{
    A *a = new A(10);

    if(a != NULL)
    {
        delete a;
        a = NULL;
    }
}

new的底层实现过程

       我们在main代码测试,为了看new的过程,我们需要进入到汇编代码,当程序运行到new断点这一行时,右键 转到反汇编,即可查看new的过程:

       在反汇编代码中可知,new动态分配内存,调用的是operator new()

      我们在回到demo_01文件,在new那一行,右键【单步执行特定函数】,即可看到new的实际操作operator new的源码。

         或者在反汇编文件的下方,也可以找到operator new的源码,在源码处打断点,待会儿可以跳转到那儿,如下:

void* __CRTDECL operator new(size_t const size)
{
    for (;;)
    {
        if (void* const block = malloc(size))
        {
            return block;
        }

        if (_callnewh(size) == 0)
        {
            if (size == SIZE_MAX)
            {
                __scrt_throw_std_bad_array_new_length();
            }
            else
            {
                __scrt_throw_std_bad_alloc();
            }
        }

        // The new handler was successful; try to allocate again...
    }
}

          由此可知,new还是调用malloc进行分配内存,如果malloc OK,即返回内存地址,如下所示:

           可知我们new出的对象和block的地址相同

 

         并且源码给出了new的调用过程

 

               代码很复杂,我用的是VS2017, 这里的代码应该有C++委员会和微软的人参与,就不过多纠结了。

 

delete的底层实现过程

           同样在delete时我们进入反汇编

       单步运行特定函数

 

       可知先执行~scalar deleting destructor, 进到A的析构函数

      下面又调用了operator delete()

 

              在该文件的下面,我们可以看到源码

         右键转到源码,

               就可以看到

            再次单步运行

 

         operator delete的源码

void __CRTDECL operator delete(void* const block) noexcept
{
    #ifdef _DEBUG
    _free_dbg(block, _UNKNOWN_BLOCK);
    #else
    free(block);
    #endif
}

       可知,delte是调用了free.

      官方的delete流程

       综上可知,

             new  ---> operator new() ---->malloc()

             delete ---> operator delete() --->free()

      我们也可以认为operator new和operator delete只是malloc和free的一层封装。

      对于对象数组的new, delete过程和以上类似,也可以查看代码分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

令狐掌门

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值