When and why is the std :: __ non_rtti_object exception thrown?

I am using Visual Studio and doing a valid dynamic translation. RTTI is on.

Edit: updated code to be more realistic

struct base { virtual base* Clone() { base* ptr = new base; CopyValuesTo( ptr ); return ptr; } virtual void CopyValuesTo( base* ptr ) { ... } virtual ~base() { } } struct derived : public base { virtual base* Clone() { derived* ptr = new derived; CopyValuesTo( ptr ); return ptr; } virtual void CopyValuesTo( base* ptr ) { ... } virtual ~derived() { } } void Class1::UseNewSpec( base* in_ptr ) //part of a totally unrelated class { derived* ptr = dynamic_cast<derived *>(in_ptr); if( !ptr ) return; delete m_ptr; m_ptr = ptr->Clone(); //m_ptr is a member of Class1 of type base* } //usage : Class1 obj; derived new_spec; obj.UseNewSpec( &new_spec ); 

My debugger says in_ptr is of the correct type when an exception is thrown. Google seems especially useless. Any ideas? Greetings.

+4
source share
5 answers

I conducted a test based on your pseudo code and it works. Therefore, if RTTI is really included in your build configuration, then this should be another problem that was not fixed in what you placed.

+5
source

http://msdn.microsoft.com/en-us/library/fyf39xec(VS.80).aspx contains information about __non_rtti_object_exception.

From MSDN:

If the pointer does not point to a valid object, a __non_rtti_object exception is thrown, which indicates to try to parse the RTTI, which caused an error (for example, access violation), because the object was somehow invalid (bad pointer or code was not compiled with / GR).

+8
source

Exceptions, crashes, or RTTI errors around dynamic_cast may indicate that you have performed an illegal listing. dynamic_cast<derived*>(ptrToBase) valid if and only if the derived class and class base satisfy the following restriction: this class or one of its base classes has a virtual member function.

This virtual member function can be any, including a destructor. If you do not have other member functions, you can try:

 struct base { virtual ~base(){} ... } struct derived : public base { ... } 

base now has a virtual member function and also outputs. Try this and see if it solves your problem.

EDIT-ADD:

@carleeto - In "he already had a virtual destructor", doe it == base?

If the derivative has a virtual destructor, but the database is not a virtual dtor, then you can still get this error.

In addition, you must make sure that the object was not destroyed - after the destructor starts, dynamic_cask is safer to call. Try adding trace to ctors and dtors.

+5
source

Make sure all source files have RTTI enabled.

Otherwise, the pointer is invalid.

+1
source

Does base support any virtual methods? This is necessary for dynamic_cast work.

0
source

All Articles