Dangling references or not? (C++)

Started by
9 comments, last by kittycat768 15 years, 3 months ago
I've become very concerned about making sure my programs don't leak memory. I understand how it works for the most part. Here's my scenario:
struct Vertex
{
	float x, y, z, nx, ny, nz;
};

struct Material
{
	float r, g, b, specr, specg, specb, spec, mirr, mirg, mirb;
	int spechard;
};

struct Face
{
	int vindex[4], mindex;
	float u[4], v[4];
	Vertex *verts[4];
	Material *mat;
};

My mesh class consists of dynamically allocated arrays of Vertex, Material, and Face structures. Each of my Face structures has 4 pointers (verts) that point to the proper vertices and 1 pointer that points to the proper material. I added these for convenience but still left in the indices for comformity. My main concern is where in my mesh destructor to clear these pointers. I figured that once all the arrays are deleted that these pointers in the face structures become unusable.. OR do they become dangling references? I'm not 100% sure whether my question is even valid. Don't hold back.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------I once read that World of Warcraft is poor fishing simulator. I don't know about you but I catch a lot more fish in World of Warcraft than I do in real life.
Advertisement
If you delete something that a pointer points to that pointer can be said to contain a dangling reference. Attempting to use it after deleting what it points to may appear to work for a while... Or it may cause your computer to do a back flip... Or it may cause a rip in the space/time continuum.

If, however your mesh destroys its contents and nothing else points to that content you will be a-ok. It only becomes a problem if you have other objects directly referencing vertexes on your mesh and you do not alert those objects when the mesh dies.

Chances are if you have a dangling pointer things will work well sometimes and will behave in a totally unpredictable manner at other times. These types of bugs can be hard to detect and fix so you are correct in being diligent.

Basically a good rule is if an object contains a reference to another object and there is a chance that other object could be deleted make sure you have some way of notifying the container... Or make the container responsible for the allocation and de-allocation of that other object.

Smart pointers are an implementation of that idea which wraps pointer functionality:

Boost Smart Pointers

[Edited by - M2tM on January 12, 2009 9:04:05 PM]
_______________________"You're using a screwdriver to nail some glue to a ming vase. " -ToohrVyk
Quote:Original post by M2tM
If you delete something that a pointer points to that pointer can be said to contain a dangling reference. Attempting to use it after deleting what it points to may appear to work for a while... Or it may cause your computer to do a back flip... Or it may cause a rip in the space/time continuum.

If, however your mesh destroys its contents and nothing else points to that content you will be a-ok. It only becomes a problem if you have other objects directly referencing vertexes on your mesh and you do not alert those objects when the mesh dies.

Chances are if you have a dangling pointer things will work well sometimes and will behave in a totally unpredictable manner at other times. These types of bugs can be hard to detect and fix so you are correct in being diligent.

Basically a good rule is if an object contains a reference to another object and there is a chance that other object could be deleted make sure you have some way of notifying the container... Or make the container responsible for the allocation and de-allocation of that other object.

Smart pointers are an implementation of that idea which wraps pointer functionality:

Boost Smart Pointers


Thanks for the advice. I've been trying really hard to implement my own memory leak detection code. In the end, my mesh data was getting corrupted. I can't explain it, so I ripped out all of the memory leak code. I've heard of Boost but haven't tried it yet. If it doesn't work out, I'm just going to go back to manually taking care of all of my memory. If I can't manage my own memory, I don't deserve to use C++. I guess a good rule of thumb for all this is "better safe than sorry."

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------I once read that World of Warcraft is poor fishing simulator. I don't know about you but I catch a lot more fish in World of Warcraft than I do in real life.
Quote:Original post by kittycat768
Quote:Original post by M2tM
If you delete something that a pointer points to that pointer can be said to contain a dangling reference. Attempting to use it after deleting what it points to may appear to work for a while... Or it may cause your computer to do a back flip... Or it may cause a rip in the space/time continuum.

If, however your mesh destroys its contents and nothing else points to that content you will be a-ok. It only becomes a problem if you have other objects directly referencing vertexes on your mesh and you do not alert those objects when the mesh dies.

Chances are if you have a dangling pointer things will work well sometimes and will behave in a totally unpredictable manner at other times. These types of bugs can be hard to detect and fix so you are correct in being diligent.

Basically a good rule is if an object contains a reference to another object and there is a chance that other object could be deleted make sure you have some way of notifying the container... Or make the container responsible for the allocation and de-allocation of that other object.

Smart pointers are an implementation of that idea which wraps pointer functionality:

Boost Smart Pointers


Thanks for the advice. I've been trying really hard to implement my own memory leak detection code. In the end, my mesh data was getting corrupted. I can't explain it, so I ripped out all of the memory leak code. I've heard of Boost but haven't tried it yet. If it doesn't work out, I'm just going to go back to manually taking care of all of my memory. If I can't manage my own memory, I don't deserve to use C++. I guess a good rule of thumb for all this is "better safe than sorry."


"Mesh data getting corrupted" would be the undefined behavior of utilizing dangling pointers I alluded to. You may want to spend some time stepping through a basic mock-up of your system to see where it deletes data or where something goes out of scope unexpectedly causing pointer references to go out the window.

But primarily playing with smaller examples will help you out more. Play around with allocating/deallocating in the constructor/destructor and see if you can't figure it out. Make sure you don't just "wing it" though because I can guarantee you won't get it right if you don't know what's handling what where when and how.
_______________________"You're using a screwdriver to nail some glue to a ming vase. " -ToohrVyk
If you want memory leak code, then just increment a counter every time you do new or malloc, and decrement it every time you delete. If at the end, the counter is greater than 0, you have a memory leak somewhere.
Check out the first gameplay video from my javascript/PHP RTS game
Just learn about the basics of C++ programming you should have been taught when you were first introduced to C++.
RAII.

And shared_ptr is made for sharing of ownership. If there is no sharing (and there shouldn't be in most code, and when there is there is usually better solutions), then don't use it.
Quote:Original post by kittycat768
I've been trying really hard to implement my own memory leak detection code.


Don't bother

Quote:If you want memory leak code, then just increment a counter every time you do new or malloc, and decrement it every time you delete. If at the end, the counter is greater than 0, you have a memory leak somewhere.


Which is a bit like saying There is a needle in that haystack. It doesn't really give you any useful information about how to deal with the leaks (which is what you actually want). Just adding the following to your apps will give you much better info: (VLD at the link above is even simpler than this....)

#ifdef _DEBUG#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>#endifint main(){  unsigned* data = new unsigned[10];  #ifdef _DEBUG  _CrtDumpMemoryLeaks();  #endif  return 0;}
Quote:Original post by RobTheBloke
Quote:Original post by kittycat768
I've been trying really hard to implement my own memory leak detection code.


Don't bother

Quote:If you want memory leak code, then just increment a counter every time you do new or malloc, and decrement it every time you delete. If at the end, the counter is greater than 0, you have a memory leak somewhere.


Which is a bit like saying There is a needle in that haystack. It doesn't really give you any useful information about how to deal with the leaks (which is what you actually want). Just adding the following to your apps will give you much better info: (VLD at the link above is even simpler than this....)

*** Source Snippet Removed ***


Sorry, that option isn't available to me. I use GCC. My VC++ is 10 years old and I don't like the express versions for download as they don't come with MFC and the IDE is stripped down. I'm probably gonna just make a log system that records every time I allocate memory and deallocate memory. I still haven't tried boost. As for the corrupted data, I don't know. The structures being allocated were from structure types nested in the class. Ex: Mesh::Vector. malloc() may have not liked that. It would allocate the vertices just fine and as soon as it would allocate the next chunk of structures (materials) one of the vertices would become corrupted. I also read that creating a pointer in a function and then returning that pointer is a no no, as the next call to the function would probably corrupt it. I don't see a way to fix THAT.

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------I once read that World of Warcraft is poor fishing simulator. I don't know about you but I catch a lot more fish in World of Warcraft than I do in real life.
Quote:Original post by kittycat768
Sorry, that option isn't available to me. I use GCC.


There are plenty options available. Stop trying to make this task harder than it is.

Quote:Original post by kittycat768
My VC++ is 10 years old and I don't like the express versions for download as they don't come with MFC and the IDE is stripped down.


But you use gcc, so why is MFC even an issue? If you really want it, it's in the windows platform SDK (along with everything else missing from the express edition - and it's also a free download). Even with the IDE stripped down, it's still a hell of a lot better than a 10 year old version of VC++.

\edit

Ok, so you need to find an old platform SDK. It's been removed in the latest one. Either way, MFC is best described as a pile of crap. The dotNet SDK is freely available, and is far more useful.

Quote:Original post by kittycat768
I'm probably gonna just make a log system that records every time I allocate memory and deallocate memory.


And you'd be wasting your time. There are plenty of tools around that will do all of this for you. Use them.

Quote:Original post by kittycat768
As for the corrupted data, I don't know. The structures being allocated were from structure types nested in the class.


And you won't find out unless you start using the proper tools for this.

Quote:I also read that creating a pointer in a function and then returning that pointer is a no no, as the next call to the function would probably corrupt it. I don't see a way to fix THAT.


I think you really have mis-understood quite a lot about pointers tbh. This is perfectly valid.

int* createInt() {  return new int;}


[Edited by - RobTheBloke on January 13, 2009 12:32:25 PM]
If you're just looking for a way to detect your memory errors and leaks, just use valgrind.
It's simply the best software ever made for that.

This topic is closed to new replies.

Advertisement