Check if memory was already freed in C - c

As you know, after we finish using dynamic variables we free() them.
However, sometimes those variables are already free()d.
I need to check if it is free to avoid double free. Would anyone give me a clue?

You can't check if it's already been free'd (the signature of free should tell you that much; it can't modify the pointer from the caller's perspective). However, you can do one of two things.
Change your design. Who is responsible for this memory? It seems as though your design does not make that clear, which is the most common reason for memory leaks. Place ownership on one part of your code and be done with it. Why would the interrupt function conditionally deallocate the memory? Why does that seem like the most logical solution?
Set the pointer to null and double free all you like. free(NULL) is perfectly valid.
I prefer option 1 and learning this lesson now will help you write better code down the road.

+1 to Ed S.'s answer.
But also, run valgrind - it will pick up many dynamic memory allocation errors quickly, and may be better at reading your code than you are.

Related

Is there any extra overhead in free that checks for a null pointer?

I am not asking if I need to check to see if a pointer is NULL before calling free, I know I do not. Rather, I am asking whether a (typical) implementation of free sacrifices time to check for a NULL pointer before deallocating, or whether the nature of the process does not actually invoke any additional overhead. For example, someone knowing what free does might imagine that its implementation might be something like this:
void free(void* ptr){
if(ptr != NULL){
<proceed with deallocation>
}
}
But this contradicts the C philosophy of not paying for what I don't use: if I know I will not pass a NULL pointer to free, there should not be a performance deficit as a result. Thus, I am pretty sure that free does not usually invoke such a cost, and in that case I would like to know how/why. I tried searching for the answer to this but I saw a hurricane of questions asking whether deleting a NULL pointer was safe instead.
EDIT: I am already satisfied with the answers and comments, though for future reference I want to make clear what it is I was asking. I was not asking from a programmer's perspective what the state of the program and my NULL pointer are after I call free on it. I was more interested in the perspective of the heap manager. To give an example of what I mean, suppose I am at a bakery and it is my job to take whatever is at the table and dump it all in the trash. It could be 5 brownies, a dozen cookies, or whatever, and yes I know this is not the best analogy but bear with me. I wanted to know if there could exist heap managers that, if for instance, there was "nothing" on the table whether my dumping "nothing" into the trash would make any difference, which would be an implicit handling of "nothing." An explicit handling of "nothing" would be my checking of the table to see if anything is on it before I try to dump it. I wanted to know if heap managers could usually handle the situation implicitly, i.e., by doing the same thing that they would normally do and incidentally also handling a NULL pointer, or explicitly, by making an explicit check to see if a pointer is NULL. As awksp's comment reveals, since it is required that nothing literally be done in the case of a NULL pointer, it must be true that an explicit check exists because treating the NULL pointer the same as the others would not be a no-op, and therefore we must check for NULL explicitly beforehand.
Here's why checking for NULL in free() is more than just a nice idea:
When you use malloc(), you don't have to remember how much memory you asked for: The heap manager does that for you. So, when you free a block, it's got to add the freed block (of the correct size) into whatever data structures it uses to hold this information.
So, how could it know the size? It could find the pointer in some other structure containing lists of all the allocated memory, but without some kind of Content-addressable-memory hardware, that's likely to be slow. So intead, most heap managers use a trick of storing metadata about the block that you were allocated in memory immediately before the pointer they give you. (it can't be
at the end of the block, because remember we don't know the actual block size...)
If the heap manager doesn't explicitly check for NULL, it will start trying to access memory at negative addresses (eg. NULL-16), which is likely to cause access violations and all sorts of other undesirable effects. MUCH better to have a trivial (if x=NULL) before the start.
Does it cause a performance hit? Possibly, but it's totally trivial compared to all the block merging, list searching, etc. that are all needed in typical heap managers.
First - calling free() on a null pointer doesn't really do anything. You don't need to check, you are covered in the case of a zero.
Second - on any modern system, checking a pointer before using it will have tiny overhead, maybe even a single clock cycle, which is literally negligible, so don't hesitate - check when there is need to. Not in the case of free() but there are numerous cases where you'd want to check.
The pointer will have to reach a CPU register before used, so an extra check for null will be very efficient. It is nothing compared to fetching data from ram or thread context switching.
actually what free does is just giving the allocated memory block ( if there is any ) back to your operating system whether it is allocated using malloc or realloc or whatever, there should be a pointer to the start of the block and the length of the block saved somewhere . it has obviously ( in most platforms ) the overhead of 8 byte for each byte allocated , which is a great overhead ( in terms of memory usage ) but it is what operating systems does in reality .
so talking about ANSII C when there is a null pointer passed to the free function according to what said above will do nothing because it points to no block of memory , so as long as it does nothing underneath the hood it will produce a time overhead .
the malloc and free implementations are always one of the biggest problems for who developing operating systems . so i will suggest to implement them once for yourself then try if you can reduce the overheads as much as possible .

how to debug memory overwrite in C?

This problem maybe has no specific answer appropriate for all situations,but is there some general principle we can respect?
Overwrite happened in own module may be a little easy,but if the overwrite is caused by another module written by other people and the program crashed random, how we can do for these?
I have had a lot of luck with a product called Purify, that performs memory bounds checking, after you include it at compile time. The Wikipedia page I linked to also lists some open source alternatives.
Memory overwrite is often caused by dangling pointers. While this is not the only case, it's quite common and so I've found one technique that's pretty useful:
By implementing your own memory allocator you can turn on a special debug mode where you write some known pattern into freed memory. You then periodically check all free memory to see if the pattern has been overwritten. If it has you assert or log or something. This will often find the culprit that's writing to some dangling pointer.
In addition, you can use the custom allocator to log the allocations made by address. So if you see that someone has overwritten address 0x30203 you can just check who that memory was allocated to.
I realize this sounds like a special case, but it's helped me out of so many cases before

How to detect where a block of memory was allocated?

A block of memory can be allocated statically, in the stack or in the heap. I want to know a way to detect if a pointer points to the heap. I work with Windows and Linux and it is not a problem a different solution for each OS. I use GCC and Mingw.
If I could know where the heap begins and where it ends, I think the problem can be solved. I think that I can detect the bottom and the top of the stack in order to know if the block is in the stack, but if there are multiple threads, then there are multiple stacks. Even I could to know where is the static memory, I think I will have problems with static memory blocks of shared libraries.
I think I will have a problem if the pointer does not point to the beginning of the block:
type* x = &(pointer[3]);
You can't.
You may try to allocate a memory on the heap at the beginning of you program, and compare the address to the pointer you want to free, but it will not be accurate in many of the cases. And what you might find and use on one platform after some research of its memory management, might not be relevant on the next.
An alternate way is to add a memory management module to your program, which will wrap the malloc, free etc. functions and will keep track of all allocated memory and will call free only if the pointer appears in his list. While this might seem like a lot of work to avoid memory leaks, I've found it very convenient many times.
EDIT
As mentioned in comments, the best way to decide is simple - free it in a place where you know if it's was located on the heap or not. I cannot tell you how easy it is in your case, but usually it shouldn't be too hard, many programs / programers did it before, and I doubt someone actually tried to check where the memory was allocated at.

Freeing Static Structures in C Library

A project I am working on involves a flight vehicle with GNC code written in a C library (.out). We must call this C code from LabVIEW (the primary avionics software) in the form of a .out library, and the nature of the software requires static pointers to store data between successive calls to the function. We call the GNC executive function at regular intervals throughout a flight. I'm now trying to call this function using a Matlab MEX wrapper in a DLL on Windows, and this has uncovered some memory management issues.
I am declaring the structures at the beginning of the function like this:
static Nav_str *Nav_IN_OUT_ptr;
static hguid_ref *Guid_IN_OUT_ptr;
static HopControl *Control_IN_OUT_ptr;
Nav_IN_OUT_ptr = (Nav_str *)malloc(sizeof(Nav_str));
Guid_IN_OUT_ptr = (hguid_ref *)malloc(sizeof(hguid_ref));
Control_IN_OUT_ptr = (HopControl *)malloc(sizeof(HopControl));
This happens during every run of the function. However, after this function is called iteratively several times, it always crashes with a memory segmentation fault after it tries to exit. My understanding was that this memory was supposed to clean itself up, is that incorrect?
In order to clean it up manually, I added these lines to the end, to be called only on a clean-up iteration:
free(Nav_IN_OUT_ptr);
free(Guid_IN_OUT_ptr);
free(Control_IN_OUT_ptr);
Is this the correct way to free this memory? Can I free this memory? Might there be another reason for the segmentation error other than C not giving up the memory properly after the last call, or Matlab not properly managing its memory? I've searched all over for someone with a similar problem (even contacting Mathworks) without much luck, so any comments or suggestions would be much appreciated.
Failing to free memory is not going to cause a segmentation fault. It's probably likely your problem lies somewhere else. The two likely conditions are:
Overflowing a buffer
Using a pointer to memory that has previously been free'd.
Using a bad pointer value, somehow set incorrectly.
Trying to free a pointer not returned by malloc'd (or already free'd)
My understanding was that this memory
was supposed to clean itself up, is
that incorrect?
Yes, you need to call free() to release the memory back to the heap. I would also suggest that you set the pointer value to null after the free, this may help you catch condition 2, from above.
Nav_IN_OUT_ptr = (Nav_str *)malloc(sizeof(Nav_str));
This code statement is questionable. What is Nav_str type? Are you sure you don't mean to use strlen(Nav_str)+1?
I also need to ask what is the purpose for making your pointers static? Static function variables are basically globals, and only to be used in rare cases.
Your code does have a memory leak - it is allocating that memory each time the function is called. Even your current method still has the memory leak - if you only call free() once, in the final iteration, then you have only freed the most recent allocation.
However, a memory leak will not generally cause a segmentation fault (unless your memory leak exhausts all available memory, causing subsequent malloc() calls to return NULL).
If you wish to have static structures that are only allocated once and re-used, you do not need to use malloc() at all - you can simply change your declarations to:
static Nav_str Nav_IN_OUT;
static hguid_ref Guid_IN_OUT;
static HopControl Control_IN_OUT;
... and use Nav_IN_OUT.field instead of Nav_IN_OUT_ptr->field, and &Nav_IN_OUT in place of Nav_IN_OUT_ptr (if you are directly passing the pointer value to other functions).
My understanding was that this memory was supposed to clean itself up, is that incorrect?
Sorry, but you were incorrect. :) Memory allocated with malloc() will persist until you manually remove it with free(). (You did get this right in the end. Hooray. :)
Is this the correct way to free this memory? Can I free this memory?
That is the correct way to free the memory, but it might not be in the correct place. In general, try to write your free() calls the same time you write your malloc() calls.
Maybe you allocate at the start of a function and then free at the end of the function. (In that case, on-stack memory use might be better, if the memory is only ever used by functions called by the original function.)
Maybe you have a foo_init() function that calls malloc() and creates associated contexts from an API, then you pass that context into other routines that operate on that data, and then you need to place the free() calls into a foo_destroy() or foo_free() or similar routine. All your callers then need to balance the foo_init() and foo_free() calls. This would be especially appropriate if you can't just write the foo_init() and foo_destroy() calls in one function; say, your objects might need to be removed at some random point in a larger event loop.
And maybe the data should just be allocated once and live forever. That would be correct for some application designs, and it's tough to tell just from the variable names whether or not these blocks of data should live forever.
Might there be another reason for the segmentation error other than C not giving
up the memory properly after the last call, or Matlab not properly managing its memory?
There sure could be; perhaps this memory is being returned too soon, perhaps some pointer is being free()ed two or more times, or you're overwriting your buffers (that malloc(sizeof(Nav_str)) call is a little worrying; it is probably just allocating four or eight bytes, based on the pointer size on your platform; and before you replace it with strlen(), note that strlen() won't leave space for a NUL byte at the end of the string; malloc(len+1); is the usual pattern for allocating memory for a string, and I get concerned any time I don't see that +1 in the call.)
Some time with valgrind would doubtless help find memory errors, and maybe some time with Electric Fence could help. valgrind is definitely newer, and can definitely handle 'large' programs better (since electric fence will allocate a new page for every malloc(), it can be expensive).

Does every malloc call have to be freed

From what I understand because malloc dynamically assigns mem , you need to free that mem so that it can be used again.
What happens if you return a char* that was created using malloc (i.e. how are you supposed to free that)
If you leave the pointer as it is
and exit the application will it be
freed.(I cant find a definite answer on this , some say yes , some say no).
The caller has to free it (or arrange for it to be freed). This means that functions that create and return resources need to document exactly how it should be freed.
Most OSes will free the memory when the program exits, as part of the definition of a "process". The C standard doesn't care what happens, it's beyond the scope of the program. Not all OSes have a full process abstraction, but desktop-style OSes certainly do.
The main reasons to free it before that are:
If you free memory as soon as possible, often a long time before process exit, your program uses less memory total.
If you don't free it, and you later want to change your program into a routine within another program, that perhaps is called many times, then suddenly you require many times as much memory as before (memory leak).
There are debugging tools that will help you identify memory leaks, by warning you about memory that is still allocated when the program exits. These don't really help much if there's a lot of deliberately-leaked junk to wade through.
If you don't free it and you hit any problems, it's much harder to go back later and find all the memory that needs freeing, than it is to do it right in the first place.
There are so many cases where you do need to free the memory (to prevent huge memory use in long-running programs), that your default strategy must be to clean pretty much everything up anyway.
The vaguely plausible reasons not to free are:
Less code.
If you have squillions of blocks to free individually, immediately before program exit, then it might be much faster to let the OS drop the whole process.
Stuff which is created on demand and stored in globals might be quite difficult to clean up safely, if you don't know exactly where it's used. Think of some kind of cache that's populated as you go along, that might have MRU rules to limit how much memory it occupies, so it's not an unlimited leak. OK, so this is one bad thing (unrestricted globals) causing another bad thing (unfreed memory), but it's worth knowing about as a reason why you might see unfreed blocks in existing code, and you can't necessarily just go in and fix them.
The reasons for freeing almost always outweigh the reasons against.
If you have a pointer to memory created by malloc, freeing that memory, using that pointer, will do the right thing. Yes, there is some magic involved; this will be taken care of by your compiler.
Yes, if you ignore the memory freeing, and exit the application, the OS will release the memory. However, it's considered bad practice to leave it unfreed. The OS may not do the right thing (especially in embedded settings), or may not do it in a timely fashion. Also, if you're running your program continuously, you may end up consuming a growing amount of memory, eventually consuming it all, and running out of memory and crashing.
Yes. If you malloc, you need to free. You are guaranteeing memory leaks while your program is running if you don't free.
Free it.
Always.
Period.
Yes, every call to malloc() has to be matched with a call to free().
To answer your specific questions:
You have to explicitly document your API telling the user whether the returned pointer has to be free()'d
The OS will free all memory allocated to the process.
If you write the function yourself: Avoid doing that.
Instead, let the caller pass a buffer, let the caller specify the buffer's size and copy the data into that buffer. That way, you can use your function from other modules that don't use the same heap (other programming languages, different C runtime...)
If you for whatever reason can not use such an interface, specify in the function's documentation that the caller has to free the returned pointer after it is done with it.
If you are using a library function: Have a look at the documentation.
If the documentation states that you have to free, do so.
If the documentation states that you don't have to, it might be some global cleanup function that has to be called to free the module's resources.
Regarding your second question, freeing before exiting is recommended. Technically it wont hurt, but when you ever want to reuse your code in a bigger project, you will be thankful that you wrote the correct cleanup in the first place.
The C standard has no concept of the system environment outside of a single program's execution, so it cannot specify what happens "after the program exits". At the same time, nowhere does it make any requirement that memory obtained with malloc should or must be released with free before a call to exit or a return from main, and I think it's pretty clear that the intention is that exiting without manually freeing memory will not leave resources tied up - much like how calling exit without closing all files first automatically closes them (including flushing them).
Now, as for whether you should or should not call free, that depends a lot on your particular program.
Any library code should free any memory that it obtained purely for internal use as soon as possible.
A library which returns allocated objects to the calling program should always provide a corresponding call to free those objects.
A library which performs any allocations as part of a global initialization (note: this is a very bad design, but sometimes inevitable) should provide a way for the application to reverse that initialization and free everything that was allocated. This is especially important if the library might ever be loaded dynamically (even as a consequence of satisfying another dynamically-loaded library's dependencies).
So far I've only talked about library code. At this point, all that's left is allocations made by the application itself or on the application's behalf by libraries. My view, and I will admit that it is unorthodox, is that freeing such objects is not just unnecessary but harmful. The main reason I say this is that most long-lived applications will have accumulated quite a bit of allocated memory which they are not making significant use of (think of the undo buffer in a word processor or the history in a browser). On a moderately loaded system, much of this data has been swapped to disk by the time the application terminates. If you want to free it, you're going to end up walking all over swapped-out memory addresses tracking down all the pointers to free,
putting useless wear on the physical components of the hard drive
making the user wait for your application to exit
causing other still-in-use applications' data to get swapped out, making them run slower
All of this in the name of a ridiculous "you must free everything you allocate" rule.
For short-lived applications, it's not so much of a big deal, but you can often simplify the implementation of short-lived applications that perform a single linear task and exit if you don't bother freeing all the memory they allocate. Think of most unix command line utilities. Is there any use to writing the loops for sed to free all its compiled regular expressions before exiting? Couldn't programmers' time be spent on something more productive?
1) The same way you'd free the memory normally, i.e.
p = func();
//...
free(p);
The trick is in making sure that you always do it...
2) Generally speaking, yes. But you should still free any memory you use as good practice. Not spending the time to figure out where to free the memory is just being lazy.
Let's take those one point at a time...
If you return a char * that you know was created with malloc, then yes, it is your responsibility to free that. You can do that with free(myCharPtr).
The OS will claim the memory back, and it won't be lost forever, but there's technically no guarantee that it will be reclaimed right when the application dies. That just depends on the operating system.
I wouldn't go so far as to say every malloc must be freed, but I would say that, no matter how long a program runs, there must be a bounded number of allocations (and total size) that won't be freed. The number need not be a static constant, but it must be specifiable in terms of something else (e.g. this program processes widgets; it will allocate one 64-byte struct for each quizzix in the largest widget). One may not know beforehand the size of the largest widget, but if e.g. one knows that the temporary storage required to process a widget is proportional to the square of its size, one might safely infer that the largest widget will be small enough that the total amount of memory stranded will be pretty slight.

Resources