1

Here's my situation:

I have .NET wrapper-objects in a C++/CLI layer that hold pointers to unmanaged C++ objects. I've implemented the finalizer so that it deletes the unmanaged memory pointed to by the wrapper-object on garbage-collection and sets the pointer to null.

Here's the problem:

I'm watching the finalizer for the .NET wrapper-object and it gets called twice and tries to delete the same memory twice, indicating that I have somehow created 2 .NET wrapper objects that go out-of-scope, and are garbage collected while I'm still expecting the wrapper object to be in scope (these wrapper objects are getting passed to a VB.NET application).

Here's my question:

Is there anyway for me to check the handle value so that I can confirm where the wrapper objects are getting created (copied or whatever)? Currently I'm looking at the handle values (EG - 0x0014fe80), but I see 3 different values for when the object is created, added to a collection, and deleted. So I'm not sure if the GC is just moving stuff around and this is the same object, or if I'm actually seeing 3 different objects that reference the same unmanaged memory. I would like to resolve the duplicate object copies if possible, but I understand that I will probably want to implement some sort of smart pointer so that this doesn't happen.

Thanks, Ian

Ian
  • 4,169
  • 3
  • 37
  • 62
  • No, this gets updated by the garbage collector as it compacts the heap. A simple way to keep track of objects is to give them a number in the constructor. Ideally, the native pointer value is enough :) – Hans Passant Oct 03 '11 at 17:02
  • Okay but what if I have something like this: `Public Sub handle_obj_callback(Wrap_Class^ obj)` ` dat_member = obj` `End Sub` I never call the constructor on the dat_member either, but it is of the same type as the argument so I just set it. Then I have two .NET objects that point to the same unmanaged memory, right, so I can't differentiate between them? – Ian Oct 03 '11 at 17:54
  • Sorry that was terrible, I can't figure out how to post code in these comments. But essentially I have a VB.NET class with a member that I never call the constructor on. Alls I do with it is set it to the value of an object that is passed to me from the C++/CLI library. So I essentially end up with 2 NET objects that reference the same unmanaged mem. – Ian Oct 03 '11 at 18:01
  • You are mixing vb.net and c++/cli syntax, hard to follow. But no, you should only be setting two references to the same object. The finalizer only runs once after both references disappear. – Hans Passant Oct 03 '11 at 18:09

2 Answers2

1

Take a look at this question
Here is an implementation of a scoped_ptr that is noncopyable and has an auto-release mechanism for unmanaged objects, by @Ben Voigt

Community
  • 1
  • 1
ali_bahoo
  • 4,732
  • 6
  • 41
  • 63
0

Yeah, I ended up modifying an auto_ptr class to be a shared pointer to ensure that the unmanaged memory is only deleted once through the smart pointer finalizer. I'm assuming I did something similar to all the other implementations; I created a static dictionary in the auto_ptr template class, using the native pointer value as the key, that is checked every time the finalizer is called to update the count of each item, or delete the memory.

Ian
  • 4,169
  • 3
  • 37
  • 62