#1
  1. No Profile Picture
    Dazed&Confused
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2002
    Location
    Tempe, AZ
    Posts
    501
    Rep Power
    127

    Freeing/NULLing Problem


    Okay this one just seems really bizarre, considering that I've been around C (albiet not indepth) for years and have never come across this problem until now.

    I have a global linked list of say, typedef 'TEST_STRUCT'.
    I have a function that pulls a single element of the list and places it into a local pointer of the same struct type.

    If I loop through and free all of the linked list elements from memory, shouldn't there be some way for that local pointer to know it's now NULL?

    Actually I guess I never came upon that before because past code environments recycled memory instead of freeing it, but this seems odd, none-the-less. So I guess I'm just wondering if there's a way for that local pointer to know what has happened, or do I just need to do away with the local variable?

    Any advice is appreciated.
  2. #2
  3. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    27
    Its termed a 'dangling pointer'.
    One that no longer points to the memory originally assigned to it (because that memory has been freed or realloced).

    Why are you not refreshing the local pointer when it tries to use the memory again? (as the local pointer will go out of scope as soon as the function exits)

    When you free a dynamicly allocated memory pointer do you set it to NULL? (so the next time the local pointer calls on it the returned address will be NULL)
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  4. #3
  5. No Profile Picture
    Dazed&Confused
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2002
    Location
    Tempe, AZ
    Posts
    501
    Rep Power
    127
    Well... if there's a term for it, that's pretty much all I needed to know. I was just curious if C might have gone through all the pointers in the program and nullified them when what they're pointing to is freed or something.

    This question was kind of academic anyway, since the problem can be avoided in my code.

    To answer your questions, though:

    Refreshing the pointer is definately a fix, but I was intentionally avoiding that in order to eliminate a function call. No matter... it's not as though the called function is a heavy one.

    And yeah, I tried setting it to NULL when it was freed. My guess is that the system was quick to place something new in the hole, invalidating the NULL value.

    Anyway.. like I said, you pretty much answered my question. Thanks for the insight.
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,091
    Rep Power
    2222
    Originally posted by dmittner
    Well... if there's a term for it, that's pretty much all I needed to know. I was just curious if C might have gone through all the pointers in the program and nullified them when what they're pointing to is freed or something.
    C doesn't believe in coddling its programmers nor in protecting them against themselves. It assumes that you must know what you're doing so if you tell it to do something it just figures that that is what you want and does it. That also means that it doesn't automatically clean up after you, but rather you need to do it yourself. Of course, some libraries may do more of that stuff for you, but then that's another programmer at work.

    Originally posted by dmittner
    And yeah, I tried setting it to NULL when it was freed. My guess is that the system was quick to place something new in the hole, invalidating the NULL value.
    How was that local pointer declared? Local variables are of the auto storage class by default. That means that they are allocated on the stack and they go away when you exit the function. Then when you come back, they'll contain whatever was previously written in those memory locations, AKA "garbage" -- exception being the ones that are explicitly initialized.

    However, if you declare a local variable to be static, then it is stored in memory and it retains its value between function calls. The only thing is that it can only be access from within that function.
  8. #5
  9. No Profile Picture
    Dazed&Confused
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2002
    Location
    Tempe, AZ
    Posts
    501
    Rep Power
    127
    Originally posted by dwise1_aol
    C doesn't believe in coddling its programmers nor in protecting them against themselves. It assumes that you must know what you're doing so if you tell it to do something it just figures that that is what you want and does it. That also means that it doesn't automatically clean up after you, but rather you need to do it yourself. Of course, some libraries may do more of that stuff for you, but then that's another programmer at work.


    Granted. I'm use to Perl which makes things quite easy on the programmer, and most of my past C work was done in code that already had safeguards in place. I'm kind of coming out into the real world of C now. :)

    How was that local pointer declared? Local variables are of the auto storage class by default. That means that they are allocated on the stack and they go away when you exit the function. Then when you come back, they'll contain whatever was previously written in those memory locations, AKA "garbage" -- exception being the ones that are explicitly initialized.

    However, if you declare a local variable to be static, then it is stored in memory and it retains its value between function calls. The only thing is that it can only be access from within that function.
    The process of code was essentially this, and keep in mind this is a dumbed down version and can easily be avoided:

    Code:
    {
        TEST_DATA *td;
        td = routineToPullPointerFromLinkedList("nameToMatch");
        routineToFreeAllLinkedListElements();
        if ( td == NULL )
            td = routineToCreateNewElement("name" ... );
    
        [...]
    }
    Unfortunately I couldn't even get that NULL check to apply -- as though 'td' wasn't NULL even despite an exlicit declaration of such in the freeing function.
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,091
    Rep Power
    2222
    Originally posted by dmittner
    The process of code was essentially this, and keep in mind this is a dumbed down version and can easily be avoided:

    Code:
    {
        TEST_DATA *td;
        td = routineToPullPointerFromLinkedList("nameToMatch");
        routineToFreeAllLinkedListElements();
        if ( td == NULL )
            td = routineToCreateNewElement("name" ... );
    
        [...]
    }
    Unfortunately I couldn't even get that NULL check to apply -- as though 'td' wasn't NULL even despite an exlicit declaration of such in the freeing function.
    OK, let's assume that routineToPullPointerFromLinkedList() returned a valid pointer, so that's what's been stored in td. That pointer address remains in td after routineToFreeAllLinkedListElements() is called. So, of course, td does not equal NULL.

    OK, it's just that it sounded like something else was going on instead. My mistake.

IMN logo majestic logo threadwatch logo seochat tools logo