0

I created an example classes (only for learning purposes) which don't have to use constructor initialization lists because I want to get the same effects using new/delete and malloc/free. What are other constraints besides not using constructor initialization list? Do you think that the following code simulate the new/delete behavior in the right way?

#include <iostream>
using namespace std;

class X
{
private:
        int* a;
public:
        X(int x)
        {
             this->a = new int;
             *(this->a) = x;
        }
        ~X() { delete this->a; }
        int getA() { return *(this->a); }
};

class Y
{
private:
        int* a;
public:
        void CTor(int x)
        {
             this->a = new int;
             *(this->a) = x;
        }
        void DTor() { delete this->a; }
        int getA(){ return *(this->a); }
};

void main()
{
     X *xP = new X(44);
     cout<<xP->getA()<<endl;
     delete xP;

     Y *yP = static_cast<Y*>(malloc(sizeof(Y)));
     yP->CTor(44);
     cout<<yP->getA()<<endl;
     yP->DTor();
     free(yP);

     system("pause");
}

Without using delete xP, destructor will be called automatically when program ends, but a free store won't be freed (i.e. free store for xP, free store for field a will be freed) . When using delete xP destructor is called and then a free store is completely freed. Please correct me if I'm wrong.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Irbis
  • 11,537
  • 6
  • 39
  • 68
  • 1
    If you don't call `delete` the destructor will not be called unless you do it manually. – Captain Obvlious Oct 21 '13 at 21:33
  • 1
    ... and if you don't call `new` the constructor will not be called. – masoud Oct 21 '13 at 21:34
  • 1
    ... Nothing more to say ... – Macmade Oct 21 '13 at 21:35
  • So destructor is called automatically only for objects which were created on stack, right ? – Irbis Oct 21 '13 at 21:39
  • 1
    @Irbis: Or for objects within another object, that are direct members (not created via new). Like my example with `std::string` in my answer. – Mats Petersson Oct 21 '13 at 21:41
  • 1
    The destructor can also be called automatically when a [smart pointer](http://msdn.microsoft.com/en-us/library/vstudio/hh279674.aspx) is used. – Clifford Oct 21 '13 at 21:49
  • 1
    @clifford: Nothing "special" about smart pointers - it's just like any other class allocated on the stack or as a member of a class, etc. – Mats Petersson Oct 21 '13 at 21:54
  • 1
    @Mats: I see your point, but the `delete` is automated, so the point is worth making I think. It differs from your point in the you referred to the destruction of direct members, whereas the target of a smart point is a dynamic object referenced by the smart pointer object rather than contained by it. – Clifford Oct 22 '13 at 16:27

2 Answers2

1

There are many subtle differences that distinguish new from malloc and delete from free. I believe they are only equivalent if the class is POD type.

I should warn that you can never mix the two types freely. A new must always be balanced by a delete and never by a free. Similarly malloc must be balanced only by free. Mixing the two results in undefined behaviour.

Ken Wayne VanderLinde
  • 18,915
  • 3
  • 47
  • 72
  • And here's a good link about POD types: http://stackoverflow.com/questions/146452/what-are-pod-types-in-c – Macmade Oct 21 '13 at 21:37
1

The actual answer to your question is that you are incorrect, not calling delete xP will lead to a memory leak. It is very likely that the OS then cleans up the memory for you, but it's not GUARANTEED by the C++ runtime library that this happens - it's something that OS's generally offer as a nice service [and very handy it is too, since it allows us to write imperfect code and have code that does things like if (condition) { cout << "Oh horror, condition is true, I can't continue" << endl; exit(2); } without having to worry about cleaning everything up when we've got something that went horribly wrong].

My main point, however, is that this sort of stuff gets very messy as soon as you add members that in themselves need destruction, e.g.

class X
{
  private:
    std::string str;
  ... 
};

There is no trivial way to call the destructor for str. And it gets even worse if you decide to use exceptions and automated cleanup.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227