Freeing memory

A

Andrea Crotti

Supposing that I have a class which takes a reference to an object in
the constructor.

MyClass:Myclass(const Other& obj)

Now I would to be able to do the following

Other obj(...);

MyClass *cl = new MyClass(obj);

and when I do a
delete cl;

Also the memory allocated by the first object gets freed.

Is that possible?
It would be fairly easy if I declare ~Myclass and I pass a pointer
instead of a reference, but it adds some more complexity which would
be nice to avoid.

If you know if it's possible somehow I would be glad to know it...
At the moment I'll just leave it like this because I don't want to do
premature optimizations, but this optimization I'm sure will be
necessary in a short time.
 
K

Kevin P. Fleming

Supposing that I have a class which takes a reference to an object in
the constructor.

MyClass:Myclass(const Other& obj)

Now I would to be able to do the following

Other obj(...);

MyClass *cl = new MyClass(obj);

and when I do a
delete cl;

Also the memory allocated by the first object gets freed.

Is that possible?
It would be fairly easy if I declare ~Myclass and I pass a pointer
instead of a reference, but it adds some more complexity which would
be nice to avoid.

If you know if it's possible somehow I would be glad to know it...
At the moment I'll just leave it like this because I don't want to do
premature optimizations, but this optimization I'm sure will be
necessary in a short time.

The only way to do this practically is to use some sort of shared
pointer (shared, unique or other, depending on the exact ownership
semantics you need). Alternatively, if you let MyClass instantiate the
Other object itself and provide access to it, then MyClass can control
the lifetime of the Other object itself.

In the example you proposed, 'obj' is not heap-allocated, so there is no
lifetime management necessary at all. If you passed in a pointer to
MyClass, you still wouldn't be able to safely call 'delete' on it,
because you can't know whether that pointer points to heap space, stack
space, or some other space. Using a shared pointer implementation
(properly) will avoid this problem.
 
A

Andrea Crotti

The only way to do this practically is to use some sort of shared
pointer (shared, unique or other, depending on the exact ownership
semantics you need). Alternatively, if you let MyClass instantiate the
Other object itself and provide access to it, then MyClass can control
the lifetime of the Other object itself.

In the example you proposed, 'obj' is not heap-allocated, so there is no
lifetime management necessary at all. If you passed in a pointer to
MyClass, you still wouldn't be able to safely call 'delete' on it,
because you can't know whether that pointer points to heap space, stack
space, or some other space. Using a shared pointer implementation
(properly) will avoid this problem.


Yes that's the problem, at the moment of the creation of the object
obj I don't know if I will need to encapsulate it in a MyClass object
or not.

So I can't manage the lifetime of the object in the other class.

I will try with a shared pointer then, thanks a lot!
 
J

James Kanze

Supposing that I have a class which takes a reference to an object in
the constructor.
MyClass:Myclass(const Other& obj)
Now I would to be able to do the following
Other obj(...);
MyClass *cl = new MyClass(obj);
and when I do a
delete cl;
Also the memory allocated by the first object gets freed.

The memory for the first object is on the stack, at least as
you've written it.
Is that possible?
It would be fairly easy if I declare ~Myclass and I pass a pointer
instead of a reference, but it adds some more complexity which would
be nice to avoid.

There's no problem from the language point of view with calling
delete on something passed as a reference; you can convert
a reference to a pointer any time you want. There is likely
a problem from a software engineering point of view: the reader
doesn't expect delete to be called on something passed as
a reference, and will not act in consequence; he will, for
example, pass an object with auto lifetime, as you've done
above. If the reference is to a const, he's even likely to pass
a temporary. (If your class saves the reference or pointer,
it's almost always a bad idea to pass it by reference to
const.)
If you know if it's possible somehow I would be glad to know it...
At the moment I'll just leave it like this because I don't want to do
premature optimizations, but this optimization I'm sure will be
necessary in a short time.

What optimization?
 
A

Andrea Crotti

What optimization?

The optimization is to free the memory as soon as possible.
The problem is that the object creating the messages in the first
place has an indefinite lifetime.

So if I just create objects all the time they will never be freed and
it will soon a catastrophe.

But if I do this

MyObj *obj = new MyObj();

and then I have
MyClass::MyClass(const MyObj& _obj)

and I create it with:
MyClass *m = new MyClass(*obj);

Then from my understanding if I define
~MyClass() {
delete obj;
}
it could work, correct?

It's a dirty hack probably though...
Since I can't use boost, any other useful smart pointer from the
standard library?
 
J

James Kanze

The optimization is to free the memory as soon as possible.
The problem is that the object creating the messages in the first
place has an indefinite lifetime.

Some sort of factory or generator, in sum. Or the classic
producer-consumer model.
So if I just create objects all the time they will never be freed and
it will soon a catastrophe.
But if I do this
MyObj *obj = new MyObj();
and then I have
MyClass::MyClass(const MyObj& _obj)
and I create it with:
MyClass *m = new MyClass(*obj);
Then from my understanding if I define
~MyClass() {
delete obj;}
it could work, correct?

It's not clear from your description who's doing what, but the
consumer-producer pattern is frequent. But I don't quite see
what you're trying to accomplish above: the producer does a new
to create the message, then passes it on to the consumer, who
does whatever he has to do with it, and deletes it. The message
object itself is passed as a pointer (smart or otherwise),
everywhere.
It's a dirty hack probably though...
Since I can't use boost, any other useful smart pointer from the
standard library?

The standard std::auto_ptr corresponds exactly to the
producer-consumer pattern, much better, in fact, than anything
in boost: once the producer passes the pointer to the consumer,
it shouldn't use it any more, since it doesn't know when and
what the consumer has done with it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top