2

I have two cases for allocation of memory using new operator.

class xx{
    public: int x;
             xx(){}
             ~xx(){}
};
class yy : public xx {
    public: int y;
             yy(){}
             ~yy(){}
};
int main(int argc, char *argv[])
{
    yy *y1 = new yy();  //y1 constructor is called
    //CASE-1
    yy *y2 = y1;
    //CASE-2             
    yy *y3 = new (y1) yy(); 
    return 0;
}

In CASE-1 I am just allocating y1 memory to y2 without destroying y1(shallow copy). Here constructor will not be called.

In CASE-2 I am allocating y1 memory to y3 to the address destroying y1. Here constructor of y3 will be called. But destructor of y1 is not called. According to my understanding application has to take precautions for null value check while using y1 and y2 in future code.

So basically I want to understand the scenarios where CASE-2 is useful as compared to CASE-1. Thanks in advance.

Santosh Sahu
  • 2,134
  • 6
  • 27
  • 51
  • 1
    I have to admit that I don't know the syntax in case 2. I didn't know you can create a new yy instance like this! Can someone confirm whether this compiles? – ABCD Sep 08 '14 at 06:20
  • it compiles dude.. you can just compile it. – Santosh Sahu Sep 08 '14 at 06:21
  • 1
    you need to call the dtor explicit before placement new. the destructor is not called automatically when you reuse the memory – AndersK Sep 08 '14 at 06:21
  • You only allocated memory when you called `new yy()`. You did not allocate any more memory after that. Placement new is used to construct an object is a specific place in memory (that must be allocated before). It can be viewed as a way to explicitly call a constructor. It does not call any destructors. – D Drmmr Sep 08 '14 at 06:44

2 Answers2

2

Before case 1 you're constructing a yy object (that also implies calling the base class constructor for xx). In case 1 you're not constructing anything but copying pointers around. That is NOT a shallow copy but a simple pointer copy.

In case 2 you're using the placement new operator to construct a second object yy (and also the base constructor xx will be called) but you're NOT allocating memory nor calling the previous object's destructor but replacing the memory content where the previous element resided at. Your code is leaking memory only once since the previous object is no longer available but the latter is (and memory hasn't been freed). Of course if the objects also managed resources and those resources needed cleanup, since you're not calling the destructor in the second case that would have been a problem.

The placement new is useful in particular circumstances like embedded programming where you often have a fixed address and you need to construct objects in that exact spot (there might be several reasons for this, also RT systems frown upon dynamic memory allocation due to predictability and timing reasons). Anyway under normal circumstances its use is often discouraged since it carries the burden of having to check if the memory allocated is big enough for the object, potential alignment and other stuff. Don't use it if you don't have to.

Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • 1
    A possible good scenario for replacement new would be a `object pool` where you don't want to reallocated memory, but rather calling ctor/dtor on existing, +1 for good answer – lifeOfPI Sep 08 '14 at 08:29
0

Case 2 is something that should be avoided. Use only in case of absolute necessity (special constraints, embedded software, and so on)

The problem is that you overwrite the object but you do not properly ends its life. So before doing such a placement new you'd have to call the destructor of the object explicitely.

Christophe
  • 68,716
  • 7
  • 72
  • 138