Flamefire
Flamefire

Reputation: 5807

Emulate pointer (including delete) with C++ class

In a bigger OpenSource project we have the problem of a dangling pointer somewhere. Instances of a polymorphic object are passed around via a pointer to it and stored in a couple of places. More specifically: A ware is passed around as a Ware* which is allocated at one point and then registered in e.g. the building that ordered it and the carrier that currently holds it (and a couple of more places) The 'owner' is the place the physically 'has' it (e.g. the carrier). So when the carrier dies, he tells the ware to tell the building that ordered it that it no longer comes --> Building removes its pointer. Then the ware is deleted and no instance should have a pointer to it.

This works in most of the cases but there seems to be some conditions where this fails and an instance still has a pointer. I want to detect this. So I thought about replacing the Ware* by a class WarePtr that acts like a shared pointer (ref-counted). So when delete is called, it can check, if the refCount==1 and assert this.

The problem: For most of the usages it is a drop-in replacement. So syntactic changes besides the replacement Ware*->WarePtr. But I'd also need to change the delete ware calls which I would like to avoid so this could be removed without the need to change this back.

Is it possible to create a class or an overload so I can actually call delete ware where it is defined as WarePtr ware?
The called function would need to check the assertion and call delete on the contained pointer. Overloading the delete operator would only allow me to intercept calls to deleting a WarePtr*...

Upvotes: 1

Views: 143

Answers (2)

Fozi
Fozi

Reputation: 5135

I understand

detection of a constraint violation without overhead in release mode

I still suggest that you switch to shared_ptr, it's the right thing to do. The overhead over plain pointers will be very small, well worth the benefits.

You can then test for the constraint violation in your destructor (or wherever you delete the pointer you gave out) like this:

  • create a weak pointer.
  • reset() the shared pointer that was holding your object to delete it.
  • assert() that the weak pointer is expired().

Upvotes: 0

Brian Bi
Brian Bi

Reputation: 119229

If WarePtr has a non-explicit conversion function to Ware*, then you can call delete on a WarePtr.

If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section.

([expr.delete]/2)

Other than that, the operand must be a pointer.

Upvotes: 4

Related Questions