Free memory in C : how to check for valid pointer? - c

I have this program which stores lots of stuff in memory via pointers to memory areas (structures, arrays), and this user that can init the program at anytime. Upon init, the program needs to free previously used memory (if any, and that's the catch) and allocate new storage with a possibly different size.
Now upon the very first init I have no idea what my pointers are pointing at: especially, I don't know if they are garbage or not. Yet in case they aren't, I need to free what they are pointing at. How do I know?

Are we talking about globals here? Because they are automatically initialized to zero. In general, your program should be written in a way, that pointers never point at garbage, but either at valid data or have a value of NULL (free(NULl) is a no-op).

With the exception that a pointer pointing to NULL does not point to anything, there is no way of checking if a given pointer points to something valid. It's your job to keep track of pointers that still point to dynamic memory. (Pointers can point to automatic and static variables and of course you must not attempt to free that.)
Plenty of folk set the pointer to NULL once they have freed the relevant memory and rely on the fact that the C standard defines free(NULL) as a no-op. So you could adopt that approach.
But over-reliance on that sort of code can be smelly as it can mask potential bugs. Just be more careful with your memory management.
Or you could build yourself one of these: https://en.wikipedia.org/wiki/Boehm_garbage_collector

Related

Why i have to assign NULL to pointer after freeing allocated memory? [duplicate]

In my company there is a coding rule that says, after freeing any memory, reset the variable to NULL. For example ...
void some_func ()
{
int *nPtr;
nPtr = malloc (100);
free (nPtr);
nPtr = NULL;
return;
}
I feel that, in cases like the code shown above, setting to NULL does not have any meaning. Or am I missing something?
If there is no meaning in such cases, I am going to take it up with the "quality team" to remove this coding rule. Please advice.
Setting unused pointers to NULL is a defensive style, protecting against dangling pointer bugs. If a dangling pointer is accessed after it is freed, you may read or overwrite random memory. If a null pointer is accessed, you get an immediate crash on most systems, telling you right away what the error is.
For local variables, it may be a little bit pointless if it is "obvious" that the pointer isn't accessed anymore after being freed, so this style is more appropriate for member data and global variables. Even for local variables, it may be a good approach if the function continues after the memory is released.
To complete the style, you should also initialize pointers to NULL before they get assigned a true pointer value.
Most of the responses have focused on preventing a double free, but setting the pointer to NULL has another benefit. Once you free a pointer, that memory is available to be reallocated by another call to malloc. If you still have the original pointer around you might end up with a bug where you attempt to use the pointer after free and corrupt some other variable, and then your program enters an unknown state and all kinds of bad things can happen (crash if you're lucky, data corruption if you're unlucky). If you had set the pointer to NULL after free, any attempt to read/write through that pointer later would result in a segfault, which is generally preferable to random memory corruption.
For both reasons, it can be a good idea to set the pointer to NULL after free(). It's not always necessary, though. For example, if the pointer variable goes out of scope immediately after free(), there's not much reason to set it to NULL.
Setting a pointer to NULL after free is a dubious practice that is often popularized as a "good programming" rule on a patently false premise. It is one of those fake truths that belong to the "sounds right" category but in reality achieve absolutely nothing useful (and sometimes leads to negative consequences).
Allegedly, setting a pointer to NULL after free is supposed to prevent the dreaded "double free" problem when the same pointer value is passed to free more than once. In reality though, in 9 cases out of 10 the real "double free" problem occurs when different pointer objects holding the same pointer value are used as arguments for free. Needless to say, setting a pointer to NULL after free achieves absolutely nothing to prevent the problem in such cases.
Of course, it is possible to run into "double free" problem when using the same pointer object as an argument to free. However, in reality situations like that normally indicate a problem with the general logical structure of the code, not a mere accidental "double free". A proper way to deal with the problem in such cases is to review and rethink the structure of the code in order to avoid the situation when the same pointer is passed to free more than once. In such cases setting the pointer to NULL and considering the problem "fixed" is nothing more than an attempt to sweep the problem under the carpet. It simply won't work in general case, because the problem with the code structure will always find another way to manifest itself.
Finally, if your code is specifically designed to rely on the pointer value being NULL or not NULL, it is perfectly fine to set the pointer value to NULL after free. But as a general "good practice" rule (as in "always set your pointer to NULL after free") it is, once again, a well-known and pretty useless fake, often followed by some for purely religious, voodoo-like reasons.
This is considered good practice to avoid overwriting memory. In the above function, it is unnecessary, but oftentimes when it is done it can find application errors.
Try something like this instead:
#if DEBUG_VERSION
void myfree(void **ptr)
{
free(*ptr);
*ptr = NULL;
}
#else
#define myfree(p) do { void ** p_tmp = (p); free(*(p_tmp)); *(p_tmp) = NULL; } while (0)
#endif
The DEBUG_VERSION lets you profile frees in debugging code, but both are functionally the same.
Edit: Added do ... while as suggested below, thanks.
If you reach pointer that has been free()d, it might break or not. That memory might be reallocated to another part of your program and then you get memory corruption,
If you set the pointer to NULL, then if you access it, the program always crashes with a segfault. No more ,,sometimes it works'', no more ,,crashes in unpredictible way''. It's way easier to debug.
Setting the pointer to the free'd memory means that any attempt to access that memory through the pointer will immediately crash, instead of causing undefined behavior. It makes it much easier to determine where things went wrong.
I can see your argument: since nPtr is going out of scope right after nPtr = NULL, there doesn't seem to be a reason to set it to NULL. However, in the case of a struct member or somewhere else where the pointer is not immediately going out of scope, it makes more sense. It's not immediately apparent whether or not that pointer will be used again by code that shouldn't be using it.
It's likely the rule is stated without making a distinction between these two cases, because it's much more difficult to automatically enforce the rule, let alone for the developers to follow it. It doesn't hurt to set pointers to NULL after every free, but it has the potential of pointing out big problems.
the most common bug in c is the double free. Basically you do something like that
free(foobar);
/* lot of code */
free(foobar);
and it end up pretty bad, the OS try to free some already freed memory and generally it segfault. So the good practice is to set to NULL, so you can make test and check if you really need to free this memory
if(foobar != null){
free(foobar);
}
also to be noted that free(NULL) won't do anything so you don't have to write the if statement. I am not really an OS guru but I am pretty even now most OSes would crash on double free.
That's also a main reason why all languages with garbage collection (Java, dotnet) was so proud of not having this problem and also not having to leave to developers the memory management as a whole.
The idea behind this, is to stop accidental reuse of the freed pointer.
Recently I come across the same question after I was looking for the answer. I reached this conclusion:
It is best practice, and one must follow this to make it portable on all (embedded) systems.
free() is a library function, which varies as one changes the platform, so you should not expect that after passing pointer to this function and after freeing memory, this pointer will be set to NULL. This may not be the case for some library implemented for the platform.
so always go for
free(ptr);
ptr = NULL;
This (can) actually be important. Although you free the memory, a later part of the program could allocate something new that happens to land in the space. Your old pointer would now point to a valid chunk of memory. It is then possible that someone would use the pointer, resulting in invalid program state.
If you NULL out the pointer, then any attempt to use it is going to dereference 0x0 and crash right there, which is easy to debug. Random pointers pointing to random memory is hard to debug. It's obviously not necessary but then that's why it's in a best practices document.
From the ANSI C standard:
void free(void *ptr);
The free function causes the space
pointed to by ptr to be deallocated,
that is, made available for further
allocation. If ptr is a null pointer,
no action occurs. Otherwise, if the
argument does not match a pointer
earlier returned by the calloc ,
malloc , or realloc function, or if
the space has been deallocated by a
call to free or realloc , the behavior
is undefined.
"the undefined behavior" is almost always a program crash. So as to avoid this it is safe to reset the pointer to NULL. free() itself cannot do this as it is passed only a pointer, not a pointer to a pointer. You can also write a safer version of free() that NULLs the pointer:
void safe_free(void** ptr)
{
free(*ptr);
*ptr = NULL;
}
I find this to be little help as in my experience when people access a freed memory allocation it's almost always because they have another pointer to it somewhere. And then it conflicts with another personal coding standard which is "Avoid useless clutter", so I don't do it as I think it rarely helps and makes the code slightly less readable.
However - I won't set the variable to null if the pointer isn't supposed to be used again, but often the higher level design gives me a reason to set it to null anyway. For example if the pointer is a member of a class and I've deleted what it points to then the "contract" if you like of the class is that that member will point to something valid at any time so it must be set to null for that reason. A small distinction but I think an important one.
In c++ it's important to always be thinking who owns this data when you allocate some memory (unless you are using smart pointers but even then some thought is required). And this process tends to lead to pointers generally being a member of some class and generally you want a class to be in a valid state at all times, and the easiest way to do that is to set the member variable to NULL to indicate it points to nothing now.
A common pattern is to set all the member pointers to NULL in the constructor and have the destructor call delete on any pointers to data that your design says that class owns. Clearly in this case you have to set the pointer to NULL when you delete something to indicate that you don't own any data before.
So to summarise, yes i often set the pointer to NULL after deleting something, but it's as part of a larger design and thoughts on who owns the data rather than due to blindly following a coding standard rule. I wouldn't do so in your example as I think there is no benefit to doing so and it adds "clutter" which in my experience is just as responsible for bugs and bad code as this kind of thing.
It is always advisable to declare a pointer variable with NULL such as,
int *ptr = NULL;
Let's say, ptr is pointing to 0x1000 memory address.
After using free(ptr), it's always advisable to nullify the pointer variable by declaring again to NULL.
e.g.:
free(ptr);
ptr = NULL;
If not re-declared to NULL, the pointer variable still keeps on pointing to the same address (0x1000), this pointer variable is called a dangling pointer.
If you define another pointer variable (let's say, q) and dynamically allocate address to the new pointer, there is a chance of taking the same address (0x1000) by new pointer variable. If in case, you use the same pointer (ptr) and update the value at the address pointed by the same pointer (ptr), then the program will end up writing a value to the place where q is pointing (since p and q are pointing to the same address (0x1000)).
e.g.
*ptr = 20; //Points to 0x1000
free(ptr);
int *q = (int *)malloc(sizeof(int) * 2); //Points to 0x1000
*ptr = 30; //Since ptr and q are pointing to the same address, so the value of the address to which q is pointing would also change.
This rule is useful when you're trying to avoid the following scenarios:
1) You have a really long function with complicated logic and memory management and you don't want to accidentally reuse the pointer to deleted memory later in the function.
2) The pointer is a member variable of a class that has fairly complex behavior and you don't want to accidentally reuse the pointer to deleted memory in other functions.
In your scenario, it doesn't make a whole lot of sense, but if the function were to get longer, it might matter.
You may argue that setting it to NULL may actually mask logic errors later on, or in the case where you assume it is valid, you still crash on NULL, so it doesn't matter.
In general, I would advise you to set it to NULL when you think it is a good idea, and not bother when you think it isn't worth it. Focus instead on writing short functions and well designed classes.
This might be more an argument to initialize all pointers to NULL, but something like this can be a very sneaky bug:
void other_func() {
int *p; // forgot to initialize
// some unrelated mallocs and stuff
// ...
if (p) {
*p = 1; // hm...
}
}
void caller() {
some_func();
other_func();
}
p ends up in the same place on the stack as the former nPtr, so it might still contain a seemingly valid pointer. Assigning to *p might overwrite all kinds of unrelated things and lead to ugly bugs. Especially if the compiler initializes local variables with zero in debug mode but doesn't once optimizations are turned on. So the debug builds don't show any signs of the bug while release builds blow up randomly...
Set the pointer that has just been freed to NULL is not mandatory but a good practice. In this way , you can avoid 1) using a freed pointed 2)free it towice
There are two reasons:
Avoid crashes when double-freeing
Written by RageZ in a duplicate question.
The most common bug in c is the double
free. Basically you do something like
that
free(foobar);
/* lot of code */
free(foobar);
and it end up pretty bad, the OS try
to free some already freed memory and
generally it segfault. So the good
practice is to set to NULL, so you
can make test and check if you really
need to free this memory
if(foobar != NULL){
free(foobar);
}
also to be noted that free(NULL)
won't do anything so you don't have to
write the if statement. I am not
really an OS guru but I am pretty even
now most OSes would crash on double
free.
That's also a main reason why all
languages with garbage collection
(Java, dotnet) was so proud of not
having this problem and also not
having to leave to developer the
memory management as a whole.
Avoid using already freed pointers
Written by Martin v. Löwis in a another answer.
Setting unused pointers to NULL is a
defensive style, protecting against
dangling pointer bugs. If a dangling
pointer is accessed after it is freed,
you may read or overwrite random
memory. If a null pointer is accessed,
you get an immediate crash on most
systems, telling you right away what
the error is.
For local variables, it may be a
little bit pointless if it is
"obvious" that the pointer isn't
accessed anymore after being freed, so
this style is more appropriate for
member data and global variables. Even
for local variables, it may be a good
approach if the function continues
after the memory is released.
To complete the style, you should also
initialize pointers to NULL before
they get assigned a true pointer
value.
To add to what other have said, one good method of pointer usage is to always check whether it is a valid pointer or not. Something like:
if(ptr)
ptr->CallSomeMethod();
Explicitly marking the pointer as NULL after freeing it allows for this kind of usage in C/C++.
Settings a pointer to NULL is to protect agains so-called double-free - a situation when free() is called more than once for the same address without reallocating the block at that address.
Double-free leads to undefined behaviour - usually heap corruption or immediately crashing the program. Calling free() for a NULL pointer does nothing and is therefore guaranteed to be safe.
So the best practice unless you now for sure that the pointer leaves scope immediately or very soon after free() is to set that pointer to NULL so that even if free() is called again it is now called for a NULL pointer and undefined behaviour is evaded.
The idea is that if you try to dereference the no-longer-valid pointer after freeing it, you want to fail hard (segfault) rather than silently and mysteriously.
But... be careful. Not all systems cause a segfault if you dereference NULL. On (at least some versions of) AIX, *(int *)0 == 0, and Solaris has optional compatibility with this AIX "feature."
To the original question:
Setting the pointer to NULL directly after freeing the contents is a complete waste of time, provided the code meets all requirements, is fully debugged and will never be modified again. On the other hand, defensively NULLing a pointer that has been freed can be quite useful when someone thoughtlessly adds a new block of code beneath the free(), when the design of the original module isn't correct, and in the case of it-compiles-but-doesn't-do-what-I-want bugs.
In any system, there is an unobtainable goal of making it easiest to the right thing, and the irreducible cost of inaccurate measurements. In C we're offered a set of very sharp, very strong tools, which can create many things in the hands of a skilled worker, and inflict all sorts of metaphoric injuries when handled improperly. Some are hard to understand or use correctly. And people, being naturally risk averse, do irrational things like checking a pointer for NULL value before calling free with it…
The measurement problem is that whenever you attempt to divide good from less good, the more complex the case, the more likely you get an ambiguous measurement. If the goal is do keep only good practices, then some ambiguous ones get tossed out with the actually not good. IF your goal is to eliminate the not good, then the ambiguities may stay with the good. The two goals, keep only good or eliminate clearly bad, would seem to be diametrically opposed, but there is usually a third group that's neither one nor the other, some of both.
Before you make a case with the quality department, try looking through the bug data base to see how often, if ever, invalid pointer values caused problems that had to be written down. If you want to make real difference, identify the most common problem in your production code and propose three ways to prevent it
As you have a quality assurance team in place, let me add a minor point about QA. Some automated QA tools for C will flag assignments to freed pointers as "useless assignment to ptr". For example PC-lint/FlexeLint from Gimpel Software says
tst.c 8 Warning 438: Last value assigned to variable 'nPtr' (defined at line 5) not used
There are ways to selectively suppress messages, so you can still satisfy both QA requirements, should your team decide so.
Long story short: You do not want to accidentally (by mistake) access the address that you have freed. Because, when you free the address, you allow that address in the heap to be allocated to some other application.
However, if you do not set the pointer to NULL, and by mistake try to de-reference the pointer, or change the value of that address; YOU CAN STILL DO IT. BUT NOT SOMETHING THAT YOU WOULD LOGICALLY WANT TO DO.
Why can I still access the memory location that I have freed? Because: You may have free the memory, but the pointer variable still had information about the heap memory address. So, as a defensive strategy, please set it to NULL.

What does uninitialized read mean?

Someone said uninitialized read is accessing an unwritten but allocated memory space.
And there’s also someone said it is accessing an unallicated memory space. So I am here to double check the meaning and BTW: Could you briefly explain what do "written" and "allocated" mean.
Hard to say without full context but here is best guesses --
uninitialized read -- you would say this when a variable or structure is read from memory without a value or default having been written to it. Thus you are reading unitialized (random) data. If a hacker could write to that memory location they could cause your system to act unexpectedly.*
TO FIX: make sure all allocated data and structures have default values written to them.
unallocated memory -- this is memory that has not specifically been marked as used by your application. This means any application or system could write to this memory and impact your system (since you are not reading from space that is designated for your application.
TO FIX: make sure you allocate all memory you use using your memory management system of choice.
*It has been pointed out that the system might behave unexpected anyway but the fact the system could be controlled by an outside agency was my point
Could you briefly explain what do "written" and "allocated" mean.
“Allocated” means the memory has been designated for a specific use.
When int x; appears inside a function in a C program, memory is automatically allocated for it. (It is automatic in that the compiler arranges for the memory to be reserved for x, so the author of this function does not have to do anything else to get that memory.) Memory can also be allocated in other ways, such as by explicit request, and C has rules for which declarations do or do not reserve memory that can be somewhat complicated.
When memory is automatically allocated in this way, it is not automatically initialized. This means the program has decided a certain part of memory will be used for x but it has not put any value into it. That memory could contain a value left over from prior use, or it could contain zero from when the operating system cleared it before assigning it to the program, or it could contain something else. (Additionally, due to the rules of the C standard and the complexities of modern compilers, memory that is not initialized can cause complications in your program. It may act in ways that are confusing to beginners.)
To ensure the memory has a defined value, you should initialize it. This can be done in the definition, as with int x = 3;, or it can be done later, as with x = 3;.
Setting an object to a value is also called writing to memory, storing to memory, storing to an object, and assigning a value. So, if you have written a value to an object, you have initialized it. (“Initialization” generally refers to the first time a value is written to a new object, but we can also say we are “reinitializing” something when we are resetting its value to a state we consider “earlier” in some sense.)
Someone said uninitialized read is accessing an unwritten but allocated memory space. And there’s also someone said it is accessing an unallicated memory space.
“Uninitialized read” is a somewhat crude term. Properly, we might say a “read of uninitialized memory,” and that is indeed reading memory that is uninitialized. Even if the memory assigned for a new object, say x, was previously used for something else, we refer to that memory as uninitialized once it has been newly designated for the new object and not yet written to.
“Uninitialized read” does not mean accessing unallocated memory.

Understanding C Memory Allocation and Deallocation

I have been recently trying to learn how to program in the C programming language.
I am currently having trouble understanding how memory is deallocated by free() in C.
What does it mean to free or release the memory?
For instance, if I have the following pointer:
int *p = malloc(sizeof(int));
When I deallocate it using free(p), what does it do? Does it somehow flag it as "deallocated", so the application may use it for new allocations?
Does it deallocates only the pointer address, or the address being pointed is also deallocated too?
I would do some experiments myself to better understand this, but I am so newbie in the subject that I don't know even how to debug a C program yet (I'm not using any IDE).
Also, what if int *p is actually a pointer to an array of int?
If I call free(p), does it deallocate the whole array or only the element it is pointing to?
I'm so eager to finally understand this, I would very much appreciate any help!
What does it mean to free or release the memory?
It means that you're done with the memory and are ready to give it back to the memory allocator.
When I deallocate it using free(p), what does it do?
The specifics are implementation dependent, but for a typical allocator it puts the block back on the free list. The allocator maintains a list of blocks that are available for use. When you ask for a chunk of memory (by calling malloc() or similar) the allocator finds an appropriate block in the list of free blocks, removes it (so it's no longer available), and gives you a pointer to the block. When you call free(), the process is reversed -- the block is put back on the free list and thereby becomes available to be allocated again.
Importantly, once you call free() on a pointer, you must not dereference that pointer again. A common source of memory-related errors is using a pointer after it has been freed. For that reason, some consider it a helpful practice to set a pointer to nil immediately after freeing it. Similarly, you should avoid calling free() on a pointer that you didn't originally get from the allocator (e.g. don't free a pointer to a local variable), and it's never a good idea to call free() twice on the same pointer.
Does it deallocates only the pointer address, or the address being pointed is also deallocated too?
When you request a block of memory from the allocator, you specify the size of the block you want. The allocator keeps track of the size of the block so that when you free the block, it knows both the starting address and the block size. When you call free(p), the block that p points to is deallocated; nothing happens to the pointer p itself.
Also, what if int *p is actually a pointer to an array of int?
An array in C is a contiguous block of memory, so a pointer to the first element of the array is also a pointer to the entire block. Freeing that block will properly deallocate the entire array.
I'm so eager to finally understand this, I would very much appreciate any help!
There are a number of good pages about memory allocation in C that you should read for a much more detailed understanding. One place you could start is with the GNU C Library manual section on memory allocation.
As alluded to above and in the other answers, the actual behavior of the allocator depends on the implementation. Your code shouldn't have any particular expectations about how memory allocation works beyond what's documented in the standard library, i.e. call malloc(), calloc(), etc. to get a block of memory, and call free() to give it back when you're done so that it can be reused.
malloc and free do whatever they want. Their expected behaviour is that malloc allocates a block of desired size in dynamic memory and returns a pointer to it. free must be able to receive one such pointer and correctly deallocate the block. How they keep track of the block size is irrelevant.
Is int *p a pointer to an array of ints ? Maybe. If you allocated sufficient space for several ints, yes.
There is a fixed and limited amount of memory in your computer, and everybody wants some. The Operating system is charged with the task of assigning ownership to pieces of memory and keeping track of it all to assure that no one messes with anyone else's.
When you ask for memory with malloc(), you're asking the system (the C runtime and the OS) to give you the address of a block of memory that is now yours. You are free to write to it and read from it at will, and the system promises that no one else will mess with it while you own it. When you de-allocate it with free(), nothing happens to the memory itself, it's just no longer yours. What happens to it is none of your business. The system may keep it around for future allocations, it may give it to some other process.
The details of how this happens vary from one system to another, but they really don't concern the programmer (unless you're the one writing the code for malloc/free). Just use the memory while it's yours, and keep your hands off while it's not.

Why are the contents pointed to by a pointer not changed when memory is deallocated using free()?

I am a newbie when it comes to dynamic memory allocation. When we free the memory using void free(void *ptr) the memory is deallocated but the contents of the pointer are not deleted. Why is that? Is there any difference in more recent C compilers?
Computers don't "delete" memory as such, they just stop using all references to that memory cell and forget that anything of value is stored there. For example:
int* func (void)
{
int x = 5;
return &x;
}
printf("%d", *func()); // undefined behavior
Once the function has finished, the program stops reserving the memory location where x is stored, any other part of the program (or perhaps another program) is free to use it. So the above code could print 5, or it could print garbage, or it could even crash the program: referencing the contents of a memory cell that has ceased to be valid is undefined behavior.
Dynamic memory is no exception to this and works in the same manner. Once you have called free(), the contents of that part of the memory can be used by anyone.
Also, see this question.
The thing is that accessing memory after it has been freed is undefined behavior. It's not only that the memory contents are undefined, accessing them could lead to anything. At least some compilers when you build a debug version of the code, actually do change the contents of the memory to aid in debugging, but in release versions it's generally unnecessary to do that, so the memory is just left as is, but anyway, that is not something you can safely rely upon, don't access freed memory, it's unsafe!
In C, parameters are passed by value. So free just can't change the value of ptr.
Any change it would make would only change the value within the free function, and won't affect the caller's variable.
Also, changing it won't be so much help. There can be multiple pointers pointing to the same piece of memory, and they should all be reset when freeing. The language can't keep track of them all, so it leaves the programmer to handle the pointers.
This is very normal, because clearing the memory location after free is an overhead and generally not necessary. If you have security concerns, you can wrap the free call within a function which clears the region before freeing. You'll also notice that this requires the knowledge of the allocation size, which is another overhead.
Actually the C programming language specifies that after the lifetime of the object, even the value of any pointer pointing to it becomes indeterminate, i.e. you can't even depend on the pointer to even retain the original value.
That is because a good compiler will try to aggressively store all the variables into the CPU registers instead of memory. So after it sees that the program flow calls a function named free with the argument ptr, it can mark the register of the ptr free for other use, until it has been assigned to again, for example ptr = malloc(42);.
In between these two it could be seen changing the value, or comparing inequal against its original value, or other similar behaviour. Here's an example of what might happen.

How to find out whether the address supplied to free() is an invalid address?

Is there any way to find out whether an address supplied to free( ) is an invalid address, before calling the free( )?
We know free( ) creates an undefined behaviour if the address is an invalid address (already freed address). So how to make sure that address is a valid one?
Thanks in advance.
If you need to do this, you have a bigger problem -- you have free'd your memory before you've finished with it, or you've not invalidated references to memory when you've finished with it. Rather than trying to stop your program double-freeing by changing free(), you should be trying to fix your pointer lifetime issues.
You may find that Valgrind can help you to work out where things are going wrong.
The behaviour on free() for invalid address is undefined, because it is unpredictable. In a low-level language like C you cannot say if address is 'valid' or 'invalid'. And there are many ways a address may be invalid. 'Already freed' is only one of the cases other include: address not allocated by malloc, the data is not actually an address (e.g. some integer or character string casted to pointer), data corruption, etc.
If you are interested in the 'already freed' case only you could try to track every memory allocation and deallocation (e.g. by using a custom malloc() and free() wrapper) but this would probably only make your code more complicated and even more error-prone.
Simple answer: no, there is no way to check if the address is invalid. Live with it or switch to a higher level language (like e.g. Python), when you don't care about memory addresses at all.
No.
In order to be more helpful we really need to know your intended usage case.
If it's that you're using the same pointers to sometimes reference memory obtained by malloc, and at other times reference string literals or automatic variables, then you should simply store a flag alongside the pointer that indicates whether it points to something obtained by malloc. Or you could simply store a second copy of the pointer called ptr_to_free that's NULL when the data does not need freeing. This also has the advantage that your "main pointer" could "move around" and point to different parts of the object, since you'd be keeping the original/base pointer to free separately.
If it's just to avoid double-free issues, you just need to fix your code so they don't happen. Setting a pointer to NULL just after you free what it points to is a sloppy trick that usually gets you most of the way there, but you probably have bigger design issues to rethink...
As others have suggested, tracking a pointer is good way of knowing if memory has been freed or not.
I would also suggest the following pointers.
Initialiase the pointer to NULL while you declare it
Once freed you initialise it to NULL again
Check if pointer is not NULL before trying to free.

Resources