Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

rick_appleton

Strange memory problems

This topic is 5278 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m having a very strange problem with my code, and I can''t for the life of me find out what''s wrong about it. I''ve always assumed that if I cast a pointer to class X to a pointer to class Y, that the addresse the pointer points to stays the same. In my project this isn''t the case for some specified classes. And this is giving me headaches, not to mention runtime errors. I''ve got some sample (simplified) code up here. The problem is that casting CModel to IResource and the other way around causes a shift in addresse. Now in this example, one could compensate for this shift, but there''s a whole resource management system behind it that knows nothing of CModel (or CTexture, CMesh, CSound, etc) but only handles IResource* items. About two hours ago, this wasn''t happening yet, but I can''t for the live of me find out what is causing this. This program runs okay, until it gets to the line where you try and delete the memory. It will try and delete res (at that moment an IResource*) and fail, because res is pointing at the wrong addresse. I would welcome any and all help.

Share this post


Link to post
Share on other sites
Advertisement
... your delete will fail because your pointer is still of the other type, and thus has the wrong information about the *size* of the object. When you cast your CModel* up to its base class of IResource*, you lose access to the CModel-specific part of the object, since IResources in general aren''t guaranteed to have (or do) any of that other stuff. Such is the nature of ISA.

Share this post


Link to post
Share on other sites
Thanks for the replies.

dmikesell: Unfortunately I can''t do that, because in the real program I need to do some CModel stuff, before I cast it to an IResource*.

Zahlman: I can understand that, but then, how can I succesfully delete model if I don''t know what type it is? In this example I do of course, but in general the resource manager won''t know that (nor will it care).

Share this post


Link to post
Share on other sites
Give IResource a virtual destructor, then calling delete through an IResource pointer to CModel object should work properly.

Share this post


Link to post
Share on other sites
Your error is in the IResource class. It needs to have a public virtual destructor.

class ABaseClass
{
public:
virtual ~ABaseClass() {}
};


The problem is that when you call delete on IResource, it is invoking the destructor for IResource and the freeing the memory. However, it knows nothing about the actual object, CModel. You need to make the destructor virtual so when you call delete on IResource, the compiler will instead invoke the destructor on the most-derived object with a non-virtual destructor, and then call the remaining destructors of the hiearchy as it winds back up to the root.

Hope that helps.

- Jason Citron
- Team nine:14, System Architect
- www.fatesforgiven.com

-------------------------
Check out screenshots of the Fates Forgiven Alpha at www.fatesforgiven.com/screenshots

Share this post


Link to post
Share on other sites
But why does the address of the pointer change? Is it safe to assume that a base class address == derived class address? What about if you cast it to void* and back to the derived type again?

Share this post


Link to post
Share on other sites
quote:
Original post by antareus
But why does the address of the pointer change?


Why not? This doesn''t ususually happen with single inheritence, but there''s no rule against it.

quote:

Is it safe to assume that a base class address == derived class address?


No.

quote:

What about if you cast it to void* and back to the derived type again?

Undefined behviour, depending on what kind of casts you use.

Share this post


Link to post
Share on other sites
So pretty much any C-based API that lets you associate "user data" (read: void*) with something falls under the nebulous "undefined behavior" umbrella?

I think I''m gonna stick to cin/cout for life then.

Share this post


Link to post
Share on other sites
Only conditionally. On most compilers, it''s safe to reinterpret_cast<> a pointer to a void * and reinterpet_cast<> the pointer back to it''s original type, but it''s not guaranteed.

A static_cast<> to a void pointer and back to the same exact pointer type is guaranteed to yield the original pointer. But a static_cast<> to a base pointer, followed by a static_cast<> to a void pointer, followed by a static_cast<> to original derived class pointer has undefined beheviour.

In this case const_casts probably don''t matter. dynamic_casts are well defined in the direction from class type pointer to void pointer, but don''t function in the opposite direction.

Basically, once you start invoking void *, you had darn well better know what the original type was, because there''s no way to get it back if you''ve forgotten it.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!