Thread: c++ Pointers and the const keyword

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    3

    c++ Pointers and the const keyword

    Hello, I'm relatively new to C++. I've worked in C# and Java a fair amount, so I have a fairly decent understanding of programming concepts.

    I've recently starting working on a mod for HL2 (not as anything commericial, just as a way for me to dive headfirst into c++ and start learning).

    I've been playing for a few days, and I've run into an issue that I think (or, at least, hope) is language specific, and I don't quite grasp the symantics fully.

    Anyway, I have a method of an object CBaseWeaponClip::SetMaxSize. It's code follows:
    Code:
    void CBaseWeaponClip::SetMaxSize( int maxSize ) {
       m_iClipSize = maxSize;
    
       // Clips hold at least a single bullet
       if ( m_iClipSize < 1 ) { m_iClipSize = 1; }
    
       if (m_iBulletsInClip > m_iClipSize) {
           m_iBulletsInClip = m_iClipSize;
       }
    }
    In another object I have a pointer
    Code:
    CBaseWeaponClip * c_cActiveClip
    I found out that the pointer changing was causing several bugs (and it didn't need to be changing), so for safety I relabled my pointer:
    Code:
    CBaseWeaponClip * const c_cActiveClip
    and changed other code using c_cActiveClip in that class appropriately.

    However, now when I run the game it crashes and tells me "The memory at location [memory location] could not be read."

    I tracked the problem to this function. Specifically changing it to:
    Code:
    void CBaseWeaponClip::SetMaxSize( int maxSize ) {
           return;
       /*m_iClipSize = maxSize;
    
       // Clips hold at least a single bullet
       if ( m_iClipSize < 1 ) { m_iClipSize = 1; }
    
       if (m_iBulletsInClip > m_iClipSize) {
           m_iBulletsInClip = m_iClipSize;
       }*/
    }
    allows the game to load and run correctly (except weapon clips are no longer implemented properly), because SetMaxSize is a critical function. I moved my "return" statement down one line:
    Code:
    void CBaseWeaponClip::SetMaxSize( int maxSize ) {
       m_iClipSize = maxSize;
       return;
       // Clips hold at least a single bullet
       /*if ( m_iClipSize < 1 ) { m_iClipSize = 1; }
    
       if (m_iBulletsInClip > m_iClipSize) {
           m_iBulletsInClip = m_iClipSize;
       }*/
    }
    and I recieved the crash again.

    I got rid of the maxSize variable (well, it was still being passed), and simply assigned 5 to m_iClipSize:

    Code:
    void CBaseWeaponClip::SetMaxSize( int maxSize ) {
       m_iClipSize = 5;
       return;
       // Clips hold at least a single bullet
       /*if ( m_iClipSize < 1 ) { m_iClipSize = 1; }
    
       if (m_iBulletsInClip > m_iClipSize) {
           m_iBulletsInClip = m_iClipSize;
       }*/
    }
    and I still recieved the crash.

    I am assuming (quite possibly incorrectly) that relabling my pointer "const" somehow is restricting me from modifying variables like m_iClipSize. Is this the case?
    If so, what is the proper fix? (It this was "mutable" was designed for?)

    If not, what am I missing, or what information do I need to include?

    As an afterthough it may be important: I am running Windows XP, with the Visual Studio 2003 compiler.

    Thank you for your time, and I appreciate any responses.

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No, that's not what's happening. The pointer itself is const, not what it points to, so there's absolutely no restriction in what you can do with the pointee.

    Seems more like for some reason, the pointer points into Nirvana, and the moment you actually access it by changing a member, it crashes.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    3
    Alright, then perhaps my error is in initalizing c_cActiveClip.

    The only class that uses CBaseWeaponClip is CBaseClipHolder. In the header file I have:
    Code:
    class CBaseClipholder {
    private:
            // ...
    	CBaseWeaponClip * const c_cActiveClip;
    	// ...
    public:
            // ...
    }
    Then, the constructor for CBaseClipHolder:
    Code:
    CBaseClipholder::CBaseClipholder( void ) : c_cActiveClip() {
    	m_iClipsHeld = 0;
    	m_iAmmoType = -1;
    
    	SetMaxClipSize(0);
    }
    Should create c_cActiveClip as a new CBaseWeaponClip (with no parameters passed). There is a constructor for CBaseWeaponClip that does not take any arguments, so that should be valid. Is there an error in here somewhere? Again, I think this is going to be a silly mistake on my part because I not that familiar with the language.

    Anyway, I appreciate the time. Does it look like this pointer is going to "Nirvana", the great null in the sky, or wherever? Or have I possibly made a mistake elsewhere.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Should create c_cActiveClip as a new CBaseWeaponClip (with no parameters passed).
    Actually it doesn't. c_cActiveClip is a pointer, and your code default initializes the pointer. That means it sets it to point to null.

    You need to actually use new to create a CBaseWeaponClip and have c_cActiveClip point to it. Of course, I don't see any reason for c_cActiveClip to be a pointer, so in reality you don't need new at all. Just change c_cActiveClip to not be a pointer (and not be const) and things should work well.

  5. #5
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    just as a general point, I'd be wary of using the HL2 sdk as a jumping off point for learning C++.
    While HL2 is technically hugely impressive, their code is not what I'd hold up as an example of correct, modern C++.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3
    Yea, I'm fairly aware of that. I've done a little C++ before, and a lot of C# and Java, so I have a general idea of what clean code actually looks like.

    I just wanted to get my hands dirty on someone elses code. Plus, I think it's a fun way to get into it.

  7. #7
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by ncallaway
    Yea, I'm fairly aware of that. I've done a little C++ before, and a lot of C# and Java, so I have a general idea of what clean code actually looks like.

    I just wanted to get my hands dirty on someone elses code. Plus, I think it's a fun way to get into it.
    true. I built a "pet strider" mod 2 years ago when I was unemployed. it allowed you to tell the strider what to shoot with it's big cannon. wasn't much, but it was fun in single player!

    you got a problem with me? let's see what my 60ft friend has to say about that... KABOOM!
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

Popular pages Recent additions subscribe to a feed