Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / June 2005

Tip: Looking for answers? Try searching our database.

NullReferenceException on exit from managed/unmanaged code.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
andrew.bell.ia@gmail.com - 06 Jun 2005 22:07 GMT
Hi,

I'm trying to put together some managed and unmanaged code.  Everything
works fine until the program exits, and I suppose the garbage collector
runs to finalize things.  Then I get:

Unhandled Exception: System.NullReferenceException: Object reference
not set to
an instance of an object.
  at std.list<int,std::allocator<int>
>.clear(list<int,std::allocator<int> >* )

  at std.list<int,std::allocator<int>
>._Tidy(list<int,std::allocator<int> >* )

  at Tab.MCell.Finalize()

I can't think why I would get a NullReferenceException in managed code.
Any ideas greatly appreciated.

The std::list is in unmanaged code:

#include <list>
#include <math.h>

using namespace std;

namespace Tab {

 class __declspec(dllexport) Cell
 {
 private:
   int _row;
   int _col;
   list<int> _vals;
 ...
  };
}

The managed code looks like:

#using <mscorlib.dll>

#include "Cell.h"

using namespace std;
using namespace System::Collections;

namespace Tab {

 public __gc class MCell
 {
 //
 // DATA
 //
 private:
   Cell __nogc *_cell;
 //
 // FUNCTIONS
 //
 public:
   MCell(Cell *c)
     { _cell = c; }
   MCell(int row, int col)
     { _cell = new Cell(row, col); }
   ~MCell()
     { _cell->~Cell(); }
...
 };
}

The unmanaged code is built with the following which makes a DLL (the
8.3 directories are just where the stl stuff is on my machine):

cl -GX  -I"C:\PROGRA~1\MIA4C6~1\include"   Cell.cc /LD /link
/libpath:"C:\PROGRA~1\MIA4C6~1\lib"

The executable gets built with:

cl -GX  -I"C:\PROGRA~1\MIA4C6~1\include"   /clr CTest.cc /link
/libpath:"C:\PROGRA~1\MIA4C6~1\lib" Cell.lib

Thanks in advance!

-- Andrew Bell
andrew.bell.ia@gmail.com
Tamas Demjen - 06 Jun 2005 23:24 GMT
> I'm trying to put together some managed and unmanaged code.  Everything
> works fine until the program exits, and I suppose the garbage collector
[quoted text clipped - 9 lines]
>     ~MCell()
>       { _cell->~Cell(); }

Is there a reason why you're calling the destructor explicitly? There's
only one case when you can (should) do it, and that's when the object is
created using the inplace new operator. So you either do

//A:
cell = new Cell(row, col);
[...]
delete cell;
cell = 0; // just in case; it helps debugging hard-to-trace bugs

--- OR ----

//B:
unsigned char buffer[sizeof(Cell)];
cell = new (buffer) (row, col);
[...]
cell->~Cell();
cell = 0; // just in case; it helps debugging hard-to-trace bugs

But you can't mix the two syntaxes, you can't construct with the
standard new operator and then call the destructor explicitly. I
recommend that you change your MCell destructor to

~MCell() { delete _cell; }

I also recommend that you stop using names beginning with an underscore,
as it may conflict with reserved words and other internal definitions,
although this is most likely not related to your problem.

Tamas
andrew.bell.ia@gmail.com - 08 Jun 2005 15:54 GMT
Thanks for your feedback.  I did figure out the problem -- things were
getting deleted more than once.  I just didn't understand the way that
things were manifesting themselves with the exception.

It is OK to explicitly call the dtor even if you have new'ed the
object.  It just isn't usually necessary or helpful.  Microsoft was
doing this in their example code that marries managed and unmanaged
code.  Heck, I wasn't sure what they were thinking, so I thought I
would try it too.  I did have a new/delete pair in my code originally.

Leading underscores certainly don't violate any language constraint.
Leading double underscores are reserved.  Leading underscores are
reserved by C implementations, but since I use them to denote member
variables, it isn't an issue.  Been doing it for many years on many
platforms without a single problem.  As you said, this was not related
to my problem:)

Thanks again,

-- Andrew Bell
Tamas Demjen - 08 Jun 2005 17:15 GMT
> It is OK to explicitly call the dtor even if you have new'ed the
> object.

Except it's going to leak, because nobody deletes the object's memory.
The destructor certainly doesn't delete any memory.

> Leading underscores certainly don't violate any language constraint.

There *is* a very real possibility that you get into a conflict, it's
not just a style issue.

http://www.informit.com/articles/article.asp?p=360435&seqNum=3&rl=1
Herb Sutter writes: "Never, ever, ever create names that begin with an
underscore or contain a double underscore; they're reserved for your
compiler and standard library vendor's exclusive use so that they have
names they can use without tromping on your code."

Tom

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.