Passing Pointers or References?

This is a discussion on Passing Pointers or References? within the C++ Programming forums, part of the General Programming Boards category; I've been working on a basic framework that contains a series of objects that are instantiated and stored globally within ...

Passing Pointers or References?

I've been working on a basic framework that contains a series of objects that are instantiated and stored globally within one super class (hope my terminology is correct). Simply put, I have a series of classes, let's go with just three for now: Game, Filesystem, Renderer.

Game contains pointers to both Filesystem and Renderer.

After Filesystem is initialized with the new operator, it's passed to Renderer.

On a WindowsXP system, this appears to work normally in both Debug and Release modes. However, once I move over to a Vista machine, the neither version works and I see bad pointer errors within the debugger.

I doubt this is a Windows problem because if it's a pointer problem (more than likely) it will eventually effect any system that it's part of.

So I guess my question is if I should continue to pass pointers to the various objects (e.g., Renderer(Filesystem *filesystem)) or should I instead be passing references to the pointers? Am I going about this entirely the wrong way?

It depends on the nature of the problem you're having when you switch over to Vista. Try to reduce the pointer problem down to one that you can reproduce and post here.
In general, references are nice and clean so long as you don't plan on changing what it is they refer to. I tend to use references for as long as I can, and then switch over to a pointer if necessary, or some smart reference class thing.

*edit* And by references I mean references to the objects to which the pointers point. Not references to pointers.

I'm not sure about that because I've gone through every variable and pointer I have access to in the debugger with a fine-tooth comb and everything appears to be correct (see below).

I've been looking at hex dumps all day and yet I don't understand why things appear perfectly normal in the debugger.

This is the definition for the Filesystem class class file. I think I'm going to change over to references anyway because the Filesystem Class is mostly an information container and should never be changed:

const char *getFile(const char *fileName); fails when I make a call to PHYSFS_ so I wonder, is it possible that the library code is failing and not my code? I would find that hard to believe considering that PHYSFS is used in dozens of other projects without apparent problems --

I built PhysFS from source code as it's not distributed as a binary package. I later installed a patch to Microsoft's linker -- is it possible that this introduced a memory problem? That same patch is not installed on the Windows XP machine?

I'm not one to jump to conclusions and I hate to blame code from somewhere else so I was wondering if there's anything immediatly obvious out of the above code that I should be concerned with. I've run the debugger for the last three days inspecting every value I could possibly get a reference out of throught the entire code base and everything appears to be properly initialized and assigned expected values (no 0xbaadf00d or other obviously erronous hex dumps).

Thanks for the time reading through this -- this is a frustrating problem and it's always good to have a second, third, fourth etc. opinion.

const char *getFile(const char *fileName); fails when I make a call to PHYSFS_ so I wonder, is it possible that the library code is failing and not my code? I would find that hard to believe considering that PHYSFS is used in dozens of other projects without apparent problems --

It's always possible that PHYSFS_ is failing, but I'd bet in favour of the problem being in your own code.

You haven't really given enough information to allow anyone to provide help though: the class definition is not enough.

There are two basic rules of code failure due to pointer molestation;

1) The cause of a failure is code executed at or before the failure.

2) Programmers tend to focus on the line where the failure is detected and don't tend to consider the "or before" clause in rule 1.

What I'm basically saying is that the cause of your failure is probably in code executed at some time before you see any symptoms. And the code causing the problem might have been executed a considerable time before the failure occurs. And, in practice, a common mistake by developers is only looking in code within a few lines of where the symptoms occur.

Originally Posted by leeor_net

I built PhysFS from source code as it's not distributed as a binary package. I later installed a patch to Microsoft's linker -- is it possible that this introduced a memory problem? That same patch is not installed on the Windows XP machine?

Without knowing the nature of the patch, it's not possible to be sure whether it is related to your problem or not. I'd bet against it (unless, of course, you have installed a patch unsupported by the vendor).

I wouldn't necessarily bet that changing pointers to references will fix your problems. The compiler will be more likely to pick up some problems (eg it is not possible to create an uninitialised reference) but some problems in yoru code will persist (eg a dangling reference - a reference to an object that no longer exists - results in the same type of symptoms as a dangling pointer).

Thanks again for the helpful replies. As I've stated, I hesitate to blame someone elses code and can only assume that the error lies in my own code -- this is especially true considering that the same code compiled on two different machines behaves, outwardly, the same (e.g., both versions appear to run correctly on WinXP but neither work on Vista). I can only assume this means that Vista is not as forgiving with memory allocation (which is a good thing if you ask me -- it forces me to find nasty bugs that might otherwise frustrate end-users).

The failure appears to happen just after I call Filesystem::getFile(const char*). The odd thing is, in the debugger, the const char* is as expected -- a proper string value. When not running in the debugger, the const char* is either 0 or obvious garbage data.

I can assume that this is from a dangling pointer or uninitialized pointer from earlier in the code and not at the actual 'failure site'. I've attempted a back trace (e.g., just stepping back through the call stack and inspecting values) but as I said, everything appears to be correct.

I'm not sure which parts of the code are truely relevant but, more importantly, I don't know how much posted code would be deemed inappropriate or unhelpful for anybody. I see little point in flooding this thread with 5 or 6 files of C++ code as it would just clutter things up and would probably not be particularly easy to read through.

As this is an open-source project that I'm working on, the code is not private and is available for anybody to look at should they find it interesting.

What are some of the things that I can try to look for that might cause a corrupoted const char*? Maybe a few clues as to what exactly I might be looking for could help me find the mistake that I've made.

Thank you again for all of your help. Everybody has been quite helpful.

So instead of guessing, can you track where it crashes in the debugger and why?
Not all debuggers initializes variables to 0. Microsoft's debugger throws an exception if an uninitialized variable is used.

So instead of guessing, can you track where it crashes in the debugger and why?
Not all debuggers initializes variables to 0. Microsoft's debugger throws an exception if an uninitialized variable is used.

No, I can't. It doesn't crash in the debugger in either debug or release and everything appears to be normal which is what is making this so frustrating and why I've posted on cprogramming.com... It only crashes when I run the program outside the debugger which isn't exactly helpful.

Sp I've resorted to using messages to let me know exactly when the program stops working. Turns out that it crashes as soon as I try to access member classes of a super class -- class Game.

I looked at the implentation and lo and behold, I do indeed return a char* that is created locally. That should have occured to me when I couldn't find a good place for a 'delete'.

One way to reduce chances of concerns like that is to return a std::string instead. std::string has copy-by-value semantics (i.e. a copy of the local string is returned, rather than a pointer to something that does not exist).

You should not use raw pointers. Use std::string instead of char*, and std::tr1::shared_ptr, or other smart pointers for other types instead of raw pointers.
And for future reference, using Microsoft's IDE, you can use JIT debugging - that is, run it normally, let it crash and then choose to debug. Very handy for these kinds of things.