释放从placement new分配的内存 [英] Freeing memory allocated from placement new

查看:138
本文介绍了释放从placement new分配的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码



  #includeiostream
#includeconio.h

using namespace std;

类样例
{
private:
int i;
public:
sample(int ii = 0):i(ii){
cout<<Constructing Object<
}

〜sample(){cout<<Destructing Object<< endl; }

void * operator new(size_t nSize,void * loc){
cout<<Inside new<< endl;
cout<<< loc<< endl;
return loc;
}

void operator delete(void * ptr){
cout<<Inside delete<< endl;
free(ptr);
}
};


int main()
{
int intArr [2];
sample * samplePtr = new(intArr)sample(5);
cout<< samplePtr<< endl;

delete samplePtr;
// samplePtr-> sample ::〜sample();
getch();
}

输出:

 里面New 
0x22ff38
构造对象
0x22ff38
破坏对象
里面删除

这里,我动态请求已经在堆栈上分配的内存。我读了,我需要显式调用析构函数一旦我完成。但是当我尝试调用删除分配在堆栈上的内存时,我得到一个调用析构函数。这是否意味着堆栈上的内存在释放析构函数后释放?



如果我动态请求在堆上分配的内存,在这种情况下,我需要调用delete,但是确实删除堆栈上的可用内存?

解决方案

正常的新操作符执行两项操作:


  1. 调用动态内存管理器获取内存块

  2. 调用构造函数


  • 调用动态内存管理器释放内存块

  • 展示位置只有一个步骤:



    所以展示位置删除只能执行一个步骤:


    1. 调用析构函数

    (原因是这样做会要求动态内存管理器删除它没有分配的块,导致未定义的行为)



    这一行是错误的:

      delete samplePtr; // WRONG 

    你需要做放置删除,这只是一个原始调用的析构函数: / p>

      samplePtr->〜sample(); // CORRECT 


    Consider the following code,

    #include "iostream"
    #include "conio.h"
    
    using namespace std;
    
    class sample
    {
          private:
                  int i;
          public:
                 sample(int ii=0) : i(ii){                         
                       cout<<"Constructing Object"<<endl; 
                       }
    
                 ~sample() { cout<<"Destructing Object"<<endl; }
    
                 void* operator new(size_t nSize, void* loc){
                       cout <<"Inside new"<<endl;
                       cout <<loc<<endl;
                       return loc;
                       }
    
                 void operator delete(void* ptr){
                      cout <<"Inside delete"<<endl;
                      free(ptr);
                      }
    };
    
    
    int main()
    {
        int intArr[2];
        sample* samplePtr = new(intArr) sample(5);
        cout <<samplePtr<<endl;
    
        delete samplePtr;  
    //    samplePtr->sample::~sample();
        getch();
    }
    

    Output:

    Inside New
    0x22ff38
    Constructing Object
    0x22ff38
    Destructing Object
    Inside Delete
    

    Here, I am dynamically requesting a memory that's already allocated on stack. I read that i need to call the destructor explicitly once i am done. But when i try and call delete for the memory allocated on stack i get a call to destructor. Does that mean that memory on stack is freed after destructor is called?

    If i dynamically request for memory that's allocated on heap earlier, in that case i need to call delete, but does delete actually free memory on stack?

    解决方案

    The normal new operator does two things:

    1. Calls dynamic memory manager to get chunk of memory
    2. Calls constructor

    The normal delete operator does the reverse

    1. Calls destructor
    2. Calls dynamic memory manager to free chunk of memory

    Placement new only does one step:

    1. Calls constructor

    So "placement delete" should only do one step:

    1. Calls destructor

    You should not call normal delete after placement new, as you have done. (The reason is that doing so would ask the dynamic memory manager to delete a block it did not allocate, resulting in undefined behaviour)

    This line is wrong:

    delete samplePtr;  // WRONG
    

    You need to do "placement delete" which is just a raw call the descructor:

    samplePtr->~sample(); // CORRECT
    

    这篇关于释放从placement new分配的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆