June 10th, 2003, 06:56 PM
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.
June 11th, 2003, 03:57 AM
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.
June 11th, 2003, 12:07 PM
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.
June 11th, 2003, 02:08 PM
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.
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.
June 11th, 2003, 02:34 PM
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. :)
The process of code was essentially this, and keep in mind this is a dumbed down version and can easily be avoided:
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.
td = routineToPullPointerFromLinkedList("nameToMatch");
if ( td == NULL )
td = routineToCreateNewElement("name" ... );
June 11th, 2003, 03:27 PM
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.