Thread: Passing Pointers or References?

  1. #1
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147

    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?

  2. #2
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    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.
    Last edited by CodeMonkey; 01-25-2009 at 10:02 PM.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    70
    Don't expect that changing the pointers to references will help much with your problem because the compiler will effectively turn references into pointers(if I'm remembering correctly).

  4. #4
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    i'll bet you $1 your pointers aren't being properly initialized.

  5. #5
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147
    Quote Originally Posted by m37h0d View Post
    i'll bet you $1 your pointers aren't being properly initialized.
    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:

    Code:
    class Filesystem
    {
    public:
    	/**
    	 * Initializes the Filesystem class, setups up PhysicsFS and sets any necessary
    	 * platform directory strings.
    	 */
    	Filesystem(const char *argv_0);
    	~Filesystem();
    
    	/**
    	 * Gets a path string to the Data directory.
    	 */
    	const char *getDataPath();
    
    	const char *getFile(const char *fileName);
    	long int getFileLength(const char *fileName);
    
    	bool addToSearchPath(const char *pathName);
    	char **getSearchPath();
    
    	const char *getCompiledVersion();
    	const char *getLinkedVersion();
    
    	const char *getLastError();
    
    private:
    	std::string mDataPath;			/**< Data path string. Specific to each platform. */
    	std::string mErrorMessage;		/**< Error Message should an error occur */
    	std::string mDirSeparator;		/**< */
    };
    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.
    Last edited by leeor_net; 01-25-2009 at 11:05 PM.

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by leeor_net View Post
    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).
    In debug mode everything is intialized to zero if leaved uninitialized in code

    so your
    if(!prt) ptr = ...

    code will work fine in debug mode and fail misarably in release
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by leeor_net View Post
    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.
    Quote Originally Posted by leeor_net View Post
    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).

  8. #8
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147
    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.
    Last edited by leeor_net; 01-26-2009 at 05:59 AM.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I suspect you may have a case of "using local data after the function return", which is undefined behaviour, and as such can cause "anything" to happen.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147
    Quote Originally Posted by Elysia View Post
    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.

    The member classes are defined within Game as such:

    Code:
    Filesystem *mFilesystem;	/**< File system functions and services. */
    Configuration *mConfiguration;	/**< Configuration parser. */
    StateManager *mStateManager;	/**< State manager */
    Renderer *mRenderer;		/**< Renderer. Initialized on startup. */
    Mixer *mMixer;			/**< Mixer. Initialized on startup. */
    Gui *mGui;			/**< GUI System and Manager. */
    Lua *mLua;			/**< Lua Script Interpreter. */
    These are all initialized in Game's Constructor:

    Code:
    Game::Game(const char *configFile, const char *argv_0)
    {
    	Logger::logFile << "Initializing subsystems..." << endl;
    
    	mFilesystem	= new Filesystem(argv_0);
    	mConfiguration	= new Configuration(configFile, mFilesystem);
    	mRenderer	= new SDL_Renderer(mConfiguration);
    	mMixer		= new SDL_Mixer(mConfiguration);
    	mStateManager	= new StateManager(mFilesystem, mRenderer, mMixer);
    	mLua		= new Lua(mFilesystem);
    	mGui		= new Gui(mRenderer, mFilesystem);
    	
    	Logger::logFile << "Subsystems initialized..." << endl;
    	Logger::logFile << "===================================\n" << endl;
    }
    This appears to succeed as the Logger functions work as expected and show up in the log file.

    Game has a function defined, ::go() which is basically a giant loop. Once I get into that function I have a line like this:

    Code:
    Logger::logFile << mConfiguration->getGraphicsHeight();
    All of the above classes have similar access functions return various values...

    -----

    As I've been writing this out I discovered that mGui has bad values in it. I thought "Maybe if I comment it..." and lo and behold it works.

    Thanks again everybody for your help. Without this forum and your replies I'd probably still be banging my head on the desk.... so thank you!

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by matsp View Post
    I suspect you may have a case of "using local data after the function return", which is undefined behaviour, and as such can cause "anything" to happen.
    That's one distinct possibility. That could be confirmed or denied by examination of the implementation of the FileSystem::getFile(const char *) function.

    Another distinct possibility is that a code executed before that function call is trashing the memory that this function happens to return (a pointer to).

    There are many other possibilities. We're dealing with undefined behaviour here: and there are both many causes and many possible symptoms.

  13. #13
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147
    Defintely making progress now.

    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'.

    Still having crashing but I'm sure it's other similar stuff. Unintialized variables, missed pointers, local variables that lose scope, etc.

  14. #14
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by leeor_net View Post
    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).

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing a string array to a function using pointers
    By asofaihp in forum C++ Programming
    Replies: 2
    Last Post: 04-13-2009, 11:31 AM
  2. Passing Pointers by reference
    By Bladactania in forum C Programming
    Replies: 10
    Last Post: 02-13-2009, 10:14 AM
  3. Passing pointers by reference
    By JOCAAN in forum C Programming
    Replies: 5
    Last Post: 12-03-2008, 11:02 PM
  4. Passing pointers to two-dimensional arrays of structs
    By dr.neil.stewart in forum C Programming
    Replies: 2
    Last Post: 09-07-2007, 10:25 AM
  5. problems passing pointers
    By doormat in forum C Programming
    Replies: 9
    Last Post: 04-11-2004, 04:38 PM