Thread: Situation where deleting a pointer doesn't work, but setting it to NULL does?

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    37

    Situation where deleting a pointer doesn't work, but setting it to NULL does?

    I was working on a project for school where we had to generate a blackjack hand and do some tests. I've setup an array of pointers thats created for each card in the hand, to a max of 5. I have it setup in the default constructor to loop through and set all of the cards to NULL, and then in my addcard() function I create 'new' cards for each card that's NULL. Everything works great, one of the requirements was to have a clearHand() function that loops through and deletes each card in the array, my problem is that delete doesn't do what I expected it to do, but setting each card to NULL does.

    So my question is, when would deleting a pointer cause a problem where setting it to NULL works instead? Am I creating the initial array wrong? I got 100% on the grade, and when i asked why it wasn't working he said not to worry about it, but I don't like to learn to do things the wrong way if I've done something wrong. (Learned a lot so far thanks to Grumpy and Elysia! )

    I can post the source if anyone wants to poke around and tell me what I did wrong.

    Output using delete: blackjack_delete.txt
    Output using NULL: blackjack_null.txt
    Last edited by Striph; 02-05-2012 at 07:27 PM.

  2. #2
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Now that I think about it, when my clearHand() function runs and deletes all the card pointers, I don't set them to NULL before the addCard() function tries to create a new card. I thought that when you deleted a pointer the value/address was blanked out, but it appears to not be the case, its showing garbage from some random address. Now I know why half the class dropped after our first pointer lab, pointers are an art it seems! lol

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Presumably you are setting the hand pointers to pre-existing card objects. In that case, you probably don't want to delete the cards when removing them from the hand. The cards basically still exist; they're just not in the hand anymore. So simply setting the pointers to NULL is what you want. Simply deleting the card objects will still leave your pointers pointing to de-allocated memory. And since they are not NULL, your algorithm (presumably) considers those hand positions to still be filled. It's often a good idea when deleting an object to set the pointer to NULL afterwards anyway. But in your case, simply setting the pointers to NULL is probably what you want.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    My guess is that your code is wrong. What you probably did was to use new, but you failed to use delete. However, related code assumed that a Card was deleted (or never existed to begin with) if the associated pointer is a null pointer. Since delete does not cause a pointer to become a null pointer, it appeared as if the delete was not working, yet the real solution was to both delete and set the pointer to be a null pointer.

    By the way, in the current version of C++, prefer using nullptr instead of NULL to set a pointer to be a null pointer.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Yeah thats exactly what I'm doing ooga, few snips of what I'm doing:

    Code:
    BlackJackHand::BlackJackHand()
    {
        // Set each of the cards, 0-4 to NULL
        for (int i = 0; i < MAX_CARDS_PER_HAND; i++)
            pCards[i] = NULL;
    }
    ...
    Code:
    bool BlackJackHand::addCard(PlayingCard *card)
    {
        for (int i = 0; i < MAX_CARDS_PER_HAND; i++)
        {
            if (pCards[i] == NULL)
            {
                pCards[i] = new PlayingCard();
                pCards[i]->setCard(card->getValue(),card->getSuit());
                return true;
            }
        }
    
        return false;
    }
    ...
    Code:
    void BlackJackHand::clearHand()
    {
        // Loops through each card in the hand, and if its not NULL, deletes the card
        for (int i = 0; i < MAX_CARDS_PER_HAND; i++)
            if (pCards[i] != NULL)
            {
                delete pCards[i];    
                pCards[i] = NULL;     
            }
    }
    Right now I uncommented the delete line and have the null setup right after it now. The examples and way the teacher taught us was that just using delete was enough. But then in his examples once he deleted the pointers he didn't reuse them after. Good to know that setting them to NULL once deleted is "the way" or consider good practices.

    Thanks laser, will do some research on that and start using nullptr instead.

    I love learning new things.
    Last edited by Striph; 02-05-2012 at 07:53 PM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Well, you did not show any code earlier, so oogabooga's comments that "simply setting the pointers to NULL is what you want" does not apply. You do want to delete, not just set null pointers.

    Actually, given that a deck of cards has a small number of cards whose quantity is known in advance, it would be simpler to create an array of PlayingCard objects (e.g., std::array<PlayingCard, 52>) and then point to them. Now, since this conforms to what oogabooga apparently had in mind, you don't need to delete since you don't new. Setting the pointers to be null pointers will suffice.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Yeah thats what this project is building towards, eventually it'll be classes for all sorts of card stuff. So far we've written the PlayingCard class, and a BlackJackHand class, I'm pretty sure the next thing is to make an actual deck and deal cards out of it and not do repeats, etc. Should be fun!

  8. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    laserlight's got me sussed! I wasn't thinking that you were creating a copy of the card. But since that's what you're doing, you'd better delete it (AND null out your pointer with the fancy new nullptr (which laserlight just taught me!)).
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  9. #9
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    You can also use std::vector<PlayingCard> instead of an array of PlayingCard. Then you don't have to worry about allocating and deleting memory. It is even better to use std::List<PlayingCard>.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Striph View Post
    Now that I think about it, when my clearHand() function runs and deletes all the card pointers, I don't set them to NULL before the addCard() function tries to create a new card. I thought that when you deleted a pointer the value/address was blanked out, but it appears to not be the case, its showing garbage from some random address. Now I know why half the class dropped after our first pointer lab, pointers are an art it seems! lol
    A pointer is literally an address. As analogy consider the address of a building. Say it's "123 C++ Street" and that the address is written on a piece of paper in your wallet. The building catches on fire and burns to the ground. Do the words "123 C++ Street" magically vanish from the paper in your wallet when that happens? No, they just refer to something that isn't there anymore.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Example from book - time(NULL) doesn't work
    By FernandoBasso in forum C Programming
    Replies: 6
    Last Post: 10-30-2011, 05:59 PM
  2. Replies: 1
    Last Post: 12-07-2010, 06:53 AM
  3. Why doesn't this pointer assignment work?
    By 6tr6tr in forum C++ Programming
    Replies: 8
    Last Post: 04-11-2008, 02:53 PM
  4. Deleting NULL.
    By Hulag in forum C++ Programming
    Replies: 2
    Last Post: 10-05-2006, 02:01 PM
  5. pointer arithmetic.. why doesn't this work?
    By Captain Penguin in forum C++ Programming
    Replies: 3
    Last Post: 12-05-2002, 09:27 AM