David Broza
David Broza

Reputation: 63

C++ creating object with *new

I have a method with my custom object as a parameter:

void processObject(Myobject instance)
{
 //some code using instance
}

I'm calling method above from another method like this:

...

processObject(*new MyObject());

...

Could this cause a memory leak? Should I call something like delete &instance in my process object method?

Thanks a lot for your help!

EDIT

ok now I know that there is memory leak, what would you suggest as the easiest way to fix this? My idea is to change this code:

void processObject(Myobject* instance)
{
 //some code using instance
    delete instance;
}

...

processObject(new MyObject());

...

I need as easy and fast way to fix this as possible (same issue in the code on many many places).

Upvotes: 0

Views: 151

Answers (4)

maxdev
maxdev

Reputation: 2576

You can not delete the instance object that the processObject procedure receives, because it is a copy of the object you created with new. Imagine it like that:

  1. You create a new object using new, this creates the object on the heap and gives you a MyObject*
  2. You dereference the pointer, therefore you have an object of type MyObject. Here you also lose the pointer, as you don't store it anywhere
  3. You pass the object to the processObject method, and as the signature of that function states, a copy of your object is created and passed to the function

As you have lost the pointer, you can not delete it anymore.

A solution would be not allocating the object with new and passing a refrence to the process method:

void processObject(MyObject& ref) {
    // do something with the reference
}

void test() {
    MyObject x;
    processObject(x);
    // do stuff with x
}

Or allocating it with new and doing this:

void processObject(MyObject* ptr) {
    // do something with the pointer
}

void test() {
    MyObject* x = new MyObject();
    processObject(x);
    // do stuff with x
    delete x;
}

Upvotes: 2

Spook
Spook

Reputation: 25929

Try:

class MyObject
{
public:
    MyObject() { std::cout << "Reporting construction of object (ptr: " << (int)this << ")\n"; }
    MyObject(const MyObject & other) { std::cout << "Reporting copy-construction of object (ptr: " << (int)this << ")\n"; }
    MyObject(MyObject && other) { std::cout << "Reporting move-construction of object (ptr: " << (int)this << ")\n"; }
    virtual ~MyObject() { std::cout << "Reporting destruction of object (ptr: " << (int)this << ")\n"; }
};

void DoSomething(MyObject obj)
{
}

int main()
{
    DoSomething(*new MyObject());
}

Result:

Reporting construction of object (ptr: 140173320)
Reporting copy-construction of object (ptr: -1078250292)
Reporting destruction of object (ptr: -1078250292)

As you see, first instance was not destroyed - thus leaked.

Upvotes: 0

doctorlove
doctorlove

Reputation: 19317

As it stands it will memory leak. You could delete the object inside the processObject function by taking the address, however the signature

void processObject(Myobject instance)

doesn't prevent someone from passing a local variable/stack object.

Myobject instance;
processObject(instance);

If this happens you can't delete the object.

Avoid using raw pointers, and avoid confusing users of your function.

Upvotes: 0

user2108150
user2108150

Reputation:

Yes, you should delete after a new, but you can not delete this newly created object.

Whenever you write *new x;, you are dereferencing a pointer into an actual reference (or object).
In your case, Myobject is passed by value and is thus copied, leaving your pointer not within stack space and thus causing a memory leak.

I suggest you use the following calling procedure with nearly the same effect: (without the memory leak):
processObject(MyObject());

I think you may have gotten the new syntax from Java, where we are forced to use it. In C++, you can simply call the constructor implicitly like this and have a new object be constructed in-place, which is then passed as function argument.
In this case the object is constructed on the stack and thereby has automatic storage duration (no memory leak).

Upvotes: 0

Related Questions