Safe memory management - C - c

I was looking for some guidelines on the net for safely managing
memory allocation/deallocation on C. But could not find some
good sources.
I thought maybe it is a good idea to pile up one, maybe on this site.
I could start with some, to indicate what I mean, maybe someone can
"improve" it, so that we have a full list of guidelines which
help us ensure (to the maximum extent) we manage memory properly.
Example :
Always initialize pointers when declared.
int*p = NULL;
Check return type of malloc
int *p = malloc(sizeof(int));
if(p==NULL)
{
/* do some error handling*/
}
Each malloc should have corresponding free
Possible problem is to free memory twice.
How to avoid that?
Assign pointer NULL after deletion.
free(p);
p=NULL;
note: As pointed in comments, this does not protect if an object had two pointers. And it was already freed using one of the pointers.
Another possible problem is to free memory which
contains some garbage or free memory not allocated by malloc.
How to avoid that?
AFAIAC this is not easy to check.
Given programmer follows previous steps,
he/she should additionally check no random/bad
memory gets assigned to pointer.
Otherwise, if one follows these guidelines this seems pretty safe way to manage
memory for me.
Any ideas? Suggestions?

EDIT: The question has changed quite a lot, so here is a sample of the "first" question:
In this guidelines one problem I see, is if somehow after malloc and before free pointer gets assigned some random trash memory - in this case, programmer should ensure this does not happen. Otherwise free will try to free trash memory and probably crash.
Just use a const pointer!
int * const p = malloc(sizeof(int));
if(p==NULL)
{
/* do some error handling*/
}
/* do what you want with p, but you won't be able to change its value */
free(p);
You don't need to initialize p as NULL, since malloc() returns NULL if an error occured.
You don't need to check if p is NULL, free() will check that for you.

The only answer is discipline. Make sure each malloc(3) has its corresponding free(3). That means defining some policy (where are such variables created and initialized, where are they destroyed) and following it rigurously. Define the part of the program responsible for managing each variable.
There are tools that help detect problems (i.e., valgrind), but fixing the mess afterwards is hard.

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.

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

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

What does "double free" mean?

As the title suggests I am new to C and have a mid-term coming up shortly. I am revising from past papers currently and a recurring theme is the double free problem. I understand that it is the process of calling free() on the same memory location twice, but I have a couple of questions that I'm not 100% sure how to answer:
Question 1: What is the result of a double free in C, and why is it such a problem?
This will cause a double free:
char* ptr = malloc(sizeof(char));
*ptr = 'a';
free(ptr);
free(ptr);
My response to this would be that it would return a 0x0 memory address and cause a system instability/crash. Also if I remember correctly, a double free can actually call malloc twice which results in a buffer overflow thus leaving the system vulnerable.
What would be the best way to briefly sum up this question?
Question 2: Describe a situation in which it is particularly easy to introduce a
double free in C?
I was thinking when passing pointers around you may accidentally free it in one function, and also free it again without realising?
Again, what is the "best" way to sum this up?
A double free in C, technically speaking, leads to undefined behavior. This means that the program can behave completely arbitrarily and all bets are off about what happens. That's certainly a bad thing to have happen! In practice, double-freeing a block of memory will corrupt the state of the memory manager, which might cause existing blocks of memory to get corrupted or for future allocations to fail in bizarre ways (for example, the same memory getting handed out on two different successive calls of malloc).
Double frees can happen in all sorts of cases. A fairly common one is when multiple different objects all have pointers to one another and start getting cleaned up by calls to free. When this happens, if you aren't careful, you might free the same pointer multiple times when cleaning up the objects. There are lots of other cases as well, though.
Hope this helps!
Because free() will consolidate adjacent regions by managing the information stored in the tags before each region. It is something like managing the double linked list. So it would be dangerous if the buffer where ptr is pointing has been overwritten by an attack string, in which fake tags can be injected.
This question has been well answered, but I add a late answer due to a "duplicate question" link, which asked "how to avoid it?"
One line is added to the example code posted.
char* ptr = malloc(sizeof(char));
*ptr = 'a';
free(ptr);
ptr = NULL; // add this
free(ptr);
Function free does nothing with a NULL pointer.
As per published C11 standard, calling free on already free memory location leads to undefined behaviour. It can lead to bizarre situations such as memory not getting allocated even when it's available, heap getting corrupt, same memory location getting allocated to different mallocs etc. Basically, it is undefined and can be anything.
ANSI C11 std can be found here. https://www.iso.org/obp/ui/#iso:std:iso-iec:9899:ed-3:v1:en
EDIT: changed NULL to already freed, based on comments. also, link now points to ISO/IEC 9899:2011(en)

malloc and scope

I am struggling to wrap my head around malloc in c - specifically when it needs to be free()'d. I am getting weird errors in gcc such as:
... free(): invalid next size (fast): ...
when I try to free a char pointer. For example, when reading from an input file, it will crash on certain lines when doing the following:
FILE *f = fopen(file,"r");
char x[256];
while(1) {
if(fgets(x,sizeof x,f)==NULL) break;
char *tmp = some_function_return_char_pointer(x); //OR malloc(nbytes);
// do some stuff
free(tmp); // this is where I get the error, but only sometimes
}
I checked for obvious things, such as x being NULL, but it's not; it just crashes on random lines.
But my REAL question is - when do I need to use free()? Or, probably more correctly, when should I NOT use free? What if malloc is in a function, and I return the var that used malloc()? What about in a for or while loop? Does malloc-ing for an array of struct have the same rules as for a string/char pointer?
I gather from the errors I'm getting in gcc on program crash that I'm just not understanding malloc and free. I've spent my quality time with Google and I'm still hitting brick walls. Are there any good resources you've found? Everything I see says that whenever I use malloc I need to use free. But then I try that and my program crashes. So maybe it's different based on a variable's scope? Does C free the memory at the end of a loop when a variable is declared inside of it? At the end of a function?
So:
for(i=0;i<100;i++) char *x=malloc(n); // no need to use free(x)?
but:
char *x;
for(i=0;i<100;i++) {
x=malloc(n);
free(x); //must do this, since scope of x greater than loop?
}
Is that right?
Hopefully I'm making sense...
malloc() is C's dynamic allocator. You have to understand the difference between automatic (scoped) and dynamic (manual) variables.
Automatic variables live for the duration of their scope. They're the ones you declare without any decoration: int x;
Most variables in a C program should be automatic, since they are local to some piece of code (e.g. a function, or a loop), and they communicate via function calls and return values.
The only time you need dynamic allocation is when you have some data that needs to outlive any given scope. Such data must be allocated dynamically, and eventually freed when it is no longer necessary.
The prime usage example for this is your typical linked list. The list nodes cannot possibly be local to any scope if you are going to have generic "insert/erase/find" list manipulation functions. Thus, each node must be allocated dynamically, and the list manipulation functions must ensure that they free those nodes that are no longer part of the list.
In summary, variable allocation is fundamentally and primarily a question of scope. If possible keep everything automatic and you don't have to do anything. If necessary, use dynamic allocation and take care to deallocate manually whenever appropriate.
(Edit: As #Oli says, you may also want to use dynamic allocation in a strictly local context at times, because most platforms limit the size of automatic variables to a much smaller limit than the size of dynamic memory. Think "huge array". Exceeding the available space for automatic variables usually has a colourful name such as "pile overrun" or something similar.)
In general, every call to malloc must have one corresponding call to free.* This has nothing to do with scope (i.e. nothing to do with functions or loops).
* Exceptions to this rule include using functions like strdup, but the principle is the same.
Broadly speaking, every pointer that is ever returned by malloc() must eventually be passed to free(). The scope of the variable that you store the pointer in does not affect this, because even after the variable is no longer in scope, the memory that the pointer points to will still be allocated until you call free() on it.
Well, the scope of the malloc'd memory lays between calls to malloc and free or otherwise until process is stopped (that is when OS cleans up for the process). If you never call free you get a memory leak. That could happen when address that you can pass to free goes out of scope before you actually used it - that is like loosing your keys for the car, car is still there but you can't really drive it. The error you are getting is most likely either because function returns a pointer to some memory that was not allocated using malloc or it returns a null pointer which you pass to free, which you cannot do.
You should free memory when you will no longer be accessing it. You should not free memory if you will be accessing it. This will give you a lot of pain.
If you don't want memory leak, you have to free the memory from malloc.
It can be very tricky. For example, if the // do some stuff has a continue, the free will be skipped and lead to memory leak. It is tricky, so we have shared_ptr in C++; and rumor has it salary of C programmer is higher than C++ programmer.
Sometimes we don't care memory leak. If the memory holds something that is needed during the whole lifetime of execution, you can choose not to free it. Example: a string for environment variable.
PS: Valgrind is a tool to help detect memory bugs. Especially useful for memory leak.
malloc(n) allocates n bytes of memory from a memory location named heap and then returns a void* type of pointer to it. The memory is allocated at runtime. Once you have allocated a memory dynamically, scope does not matter as long as you keep a pointer to it with you(or the address of it specifically). For example:
int* allocate_an_integer_array(int n)
{
int* p = (int*) (malloc(sizeof(int)*n));
return p;
}
This functions simply allocates memory from heap equal to n integers and returns a pointer to the first location. The pointer can be used in the calling function as you want to. The SCOPE does not matter as long as the pointer is with you..
free(p) returns the memory to heap.
The only thing you need to remember is to free it as if you don't free it and lose the value of its address, there will bw a memory leak. It is so because according to OS, you are still using the memory as you have not freed it and a memory leak will happen..
Also after freeing just set the value of the pointer to null so that u don't use it again as the same memory may be allocated again at any other time for a different purpose....
So, all you need to do is to be careful...
Hope it helps!

Already freed memory

Is there any way in C to know if a memory block has previously been freed with free()? Can i do something like...
if(isFree(pointer))
{
//code here
}
Ok if you need to check whether a pointer has already been freed you may want to check your design. You should never have to either track reference count on a pointer or if it's freed. Also some pointers are not dynamically allocated memory so I hope you mean ones called with malloc(). This is my opinion but again if you have a solid design you should know when the things your pointers point to are done being used.
The only place I have seen this not work is in monolithic kernels because pages in memory need a usage count because of shared mappings among other things.
In your case simply set unused pointers to NULL and check that. This gives you a guaranteed way of knowing in the case that you have unused fields in structures that were malloced. A simple rule is wherever you free a pointer that needs to be checked in the above way just set it to NULL and replace isFree() with if pointer == NULL. This way no reference count needs to be tracked and you know for sure if your pointer is valid and not pointing to garbage.
No, there is no way.
You can, however, use a little code discipline as follows:
Always always always guard allocations with malloc:
void * vp;
if((vp = malloc(SIZE))==NULL){
/* do something dreadful here to respond to the out of mem */
exit(-1);
}
After freeing a pointer, set it to 0
free(vp); vp = (void*)0;
/* I like to put them on one line and think of them as one peration */
Anywhere you'd be tempted to use your "is freed" function, just say
if(vp == NULL)[
/* it's been freed already */
}
Update
#Jesus in comments says:
I can't really recommend this because as soon as you're done with that
memory the pointer should go out of scope immediately (or at least at
the end of the function that releases it) these dangling pointers
existence just doesn't sit right with me.
That's generally good practice when possible; the problem is that in real life in C it's often not possible. Consider as an example a text editor that contains a doubly-linked list of lines. The list is really simple:
struct line {
struct line * prev;
struct line * next;
char * contents;
}
I define a guarded_malloc function that allocates memory
void * guarded_malloc(size_t sz){
return (malloc(sz)) ? : exit(-1); /* cute, eh? */
}
and create list nodes with newLine()
struct line * newLine(){
struct line * lp;
lp = (struct line *) guarded_malloc(sizeof(struct line));
lp->prev = lp->next = lp-contents = NULL ;
return lp;
}
I add text in string s to my line
lp->contents = guarded_malloc(strlen(s)+1);
strcpy(lp->contents,s);
and don't quibble that I should be using the bounded-length forms, this is just an example.
Now, how can I implement deleting the contents of a line I created with the char * contents going out of scope after freeing?
I see nobody has addressed the reason why what you want is fundamentally impossible. To free a resource (in this case memory, but the same applies to basically any resource) means to return it to a resource pool where it's available for reuse. The only way the system could provide a reasonable answer to "Has the memory block at address X already been freed?" is to prevent this address from ever being reused, and store with it a status flag indicating whether it was "freed". But in this case, it has not actually been freed, since it is not available for reuse.
As others have said, the fact that you're trying to answer this question means you have fundamental design errors you need to address.
In general the only way to do this portably is to replace the memory allocation functions. But if you're only concerned about your own code, a fairly common technique is to set pointers to NULL after you free() them, so any subsequent use will throw an exception or segfault:
free(pointer);
pointer = NULL;
For a platform-specific solution, you may be interested in the Win32 function IsBadReadPtr (and others like it). This function will be able to (almost) predict whether you will get a segmentation fault when reading from a particular chunk of memory.
Note: IsBadReadPtr has been deprecated by Microsoft.
However, this does not protect you in the general case, because the operating system knows nothing of the C runtime heap manager, and if a caller passes in a buffer that isn't as large as you expect, then the rest of the heap block will continue to be readable from an OS perspective.
Pointers have no information with them other than where they point. The best you can do is say "I know how this particular compiler version allocates memory, so I'll dereference memory, move the pointer back 4 bytes, check the size, makes sure it matches..." and so on. You cannot do it in a standard fashion, since memory allocation is implementation defined. Not to mention they might have not dynamically allocated it at all.
On a side note, I recommend reading 'Writing Solid Code' by Steve McGuire. Excellent sections on memory management.

Resources