Freeing memory allocated from placement new

我怕爱的太早我们不能终老 提交于 2020-01-04 06:25:15

问题


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?


回答1:


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



回答2:


What you're doing (free memory with free that was not allocated by malloc) causes undefined behavior - anything could happen. Same with deleteing a pointer that was not obtained via new. Same with deleteing a pointer obtained from malloc or the opposite.

Just because it appears to "work" doesn't mean it is correct. You must not free stack memory. You are correct that you need to call the destructor directly in this case.




回答3:


This is why placement new can be bad (in fact you should avoid it where possible, in this case, just stack allocate the object), you shouldn't delete the memory (because it was never created by new in the first place, rather, you need to do samplePtr->~sample();



来源:https://stackoverflow.com/questions/9888692/freeing-memory-allocated-from-placement-new

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!