My question is regarding when using free() is appropriate in C. I'm using gcc 4.3.2.
Suppose, if had to deallocate a bunch of memory, in a linked list, the ideal way to go about it is(I'm guessing):
int freeLL(node *a)
{
if(a->next != NULL)
freeLL(a->next);
free(a);
return 0;
}
Now, suppose I were to do a similar thing on the following ADT:
A pointer "VertexNode" which has 2 more pointers: "Vertex" and "Edge"(say). Equivalent to saying:
struct vertexnode
{
vertex *v;
edge *e;
}
typedef struct vertexnode* VertexNode;
Later, when initializing an instance, I'll do something like -
VertexNode V = malloc(sizeof(struct vertexnode));
V->v = malloc(sizeof(vertex));
So, ultimately while freeing: I used the same analogy as I used for the linked list.
free(V->v);
free(V);
This gave a runtime error, and when I commented out "free(V->v)", the program worked fine.
My questions are:
a) Is simply doing free(V) sufficient? I mean, does free() work recursively on all pointers inside a given pointer?
b) If not, is there a memory leak in this case? And how do I ideally prevent that?
c) Lastly, is there a way I can keep track of how many bytes were allocated by malloc() and
how many of them were freed by free()?
I'm very sorry for the long question. Thank you in advance for your time and patience.
No, free does not work recursively, therefore you would indeed have memory leaks. The runtime error you are occuring is probably realated to a logic error (maybe V->v is NULL or you did not alloc it before freeing).
If you are working with linux, using valgrind can help you profiling your program and mention leak errors. Compile using cc *.c -ggdb and then run valgrind --leakcheck=full ./a.out will output leak errors.
To answer your question:
a) No. free() doesn't recursively free struct's member pointers.
b) Yes, there is memory leak in that case. You have to free all allocated memory with your code.
c) You may use tool to check memory leak, such as valgrind, that's easy. And I know some projects implements their own memory management, they wrap malloc and free in their own APIs, so that you can track memory usage in their APIs.
For a complete memory management I would to have a memory pool. This would take away all the pain of having to call a number of free's for each malloc that is called. I use Apache Portable runtime (APR) for doing memory pooling. Just allocate a chunk of memory at the start to initialize. The allocate as much as you want for each pointer. Then at the end just make one call to free all the memory. This is much more efficient then doing lots of mallocs and frees that leads to memory leaks.
As a side note. I suggest you use valgrind to test you application if you don't use the memory pool. In fact you should always use valgrind.
The thing is: you need to make sure that the pointer you're trying to free is actually initialized.
I'd also check whether V->v is not NULL before calling free on it (see my comment on your question).
free is not "recursive". You're leaking memory if you don't free e and v (in your example) as well.
A: free() does not work recursively.
- If you're on the ADT concept, then I suggest you perform the allocation inside the type by creating a createVertexNode() function, and do the checking and deallocation inside a freeVertexNode() function
B: If you wasn't able to free it, then it will be a memory leak
- you can avoid it by making sure your ADT functions check and free the memory it allocates, or ...
C: Use a memory leak checker. Visual Studio has a built-in one, or use other such as valgrind or Rational Purify. I'm sure there are more free open source libraries that, at the simplest, override the malloc() and free() calls
Basically the thing to remember is calls to malloc()/free() should be 1:1. If I call malloc() to get some memory, I need to call free() to return it when I'm done.
This answers question a), no it's not recursive. (or else one call to free() would be good enough).
b) You bet there'd be a memory leak! Think about some simple code:
typedef struct pointless {
struct pointless * next;
}pl;
pl * head = malloc(sizeof(pl)); // head gets 4 bytes
pl->next = malloc(sizeof(pl)); // head->next gets 4 bytes
free(head); // head's allocated 4 bytes are deleted
Obviously this is a pointless list, since it just points to the next empty element, but it illustrates the point. My total list has 8 bytes allocated to it (4 for head, 4 for head's next). When I call free() it works on head's 4 bytes, but that's it.
This is a good thing it works this way! Think about deleting a single item from the middle of a linked list, you want to free the memory for that node, but not the whole thing! However given my above example, you'd have a memory leak as head->next wasn't free'd; and once you call free(head) there's no guarantee that you can access head->next anymore. It's possible of course... but UB at this point.
c) memory management at that level is done by the OS. If you want to keep track of how much you allocated/freed you'd have to do something like:
int total_mem = 0;
head = malloc((total_mem += sizeof(pl)));
free(head);
total_mem -= sizeof(head);
Of course you could put wrappers around the malloc() and free() calls to do the math for you which would be much more manageable, but you get the idea.
Related
I would be very glad if someone could help me in understanding completely the differences between the following codes:
// Code (1)
void f1 ( void ){
int * ptr1 = malloc ( sizeof(int) );
}
and
// Code (2)
void f2 ( void ){
int * ptr2 = malloc ( sizeof(int) );
free(ptr2);
}
As far I know, the instruction free is useful for deallocating the used memory, but on the other hand I know that every time we call a function g, if here there are new variables to be declared, they will be created and destroyed (i.e. deallocated, right?) after the execution of g.
Consequently:
do we need to use the instruction free in Code(2), or it is superfluous? (but maybe suggested for making the code more clear)
Thanks
Ps: you may be also interested in helping me with My previous related question. There, some users suggested to use the dynamic allocation of memory, and I am trying to understand why/how to.
No. malloc will not free the allocated memory. You need to use free to free the allocated chunk.
It is also the case that at the end of the program (main function) the allocated memory automatically freed by the system, but better to free it explicitly.
Always remember that the lifetime of dynamically allocated memory is till the end of the program if it is not deallocated specifically.
As said previously, memory allocated by malloc should be unallocated by free, or else you'll get memory leaks. What confuses you is that the ptr1var itself is unallocated (not the memory it's pointing to). The allocated memory is not a variable. So when you exit f1, you have no way to access your allocated memory any more, as you've lost the address.
BTW you've not explained why you need new addresses in your previous question.
No, you have to use free (or realloc)
From http://www.cplusplus.com/reference/cstdlib/malloc/:
If the function reuses the same unit of storage released by a deallocation function (such as free or realloc), the functions are synchronized in such a way that the deallocation happens entirely before the next allocation.
More information: How do malloc() and free() work?
No, malloc() will not release the memory when the function terminates.
If I may offer a suggestion though ...
If you want to allocate space (for a (very) small object) only throughout a (non-recursive) function you can use C99's variable length arrays
int foobar(size_t small_n) {
struct whatever autorelease[small_n]; // C99 VLA
// use autorelease
// no need to free
return 0;
} // memory for autorelease object released
In addition to other answers explaining about C dynamic memory allocation and the need to explicitly call free for each malloc-ed data (and when to call free is an issue; you want to avoid memory leaks), and you'll find a tool like valgrind helpful, you could also consider using Boehm's garbage collector. You basically could replace malloc by GC_malloc in your entire program and not bother a lot about explicit free-ing.
Of course, read the wikipage on garbage collection, and later the
GC handbook. It does have some caveats. So Boehm's GC is not a silver bullet.
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.
I have a need to get heap memory in big chunks. And these memory chunks will be used as memory pools, and will not be released until the process exits.
So, the traditional malloc may be not as simple (nor as fast) as I want.
I think, a stack-like allocation (LIFO) would be more efficient than malloc.
Is there any existing libraries can do that?
Or should I write a new one for this purpose?
PS: I guess obstack best describes what I'm talking about. Any other candidate or introduction about obstack?
Listen to everyone else saying to just use malloc efficiently first, but if you really do need a region-based allocator, that can free stuff in big lumps, look to the Apache Portable Runtime library.
From Wikipedia:
In C, the library function malloc is used to allocate a block of memory on the heap.
malloc will be plenty simple and fast.
Also, what does this mean?
I think it will be OK to regard the heap memory allocation as the way on stack.
If you mean you want to use stack space for your memory pool, you'll be disappointed. The stack is typically only a few MB (precise size depending on the machine and ?compiler). Perhaps you have your ideas of stack and heap backwards? The stack is where function frames, with arguments and local variables, go; the heap is where persistent, dynamically allocated memory goes.
malloc causes slowdown when it's called over and over again, like in the middle of a triply-nested loop. If you're allocating a few large chunks with malloc and holding on to them for a long time, you're already using malloc efficiently.
For example, suppose you're working with 3D point data, and you have a struct Point. If you worked with a Point ** array and allocated each point individually, like:
for (int i = 0; i < size; ++i)
points[i] = malloc(sizeof(struct Point));
it would be slow. But working with a block of struct Point instead of struct Point *, you figure out the size ahead of time and only call malloc once.
points = malloc(sizeof(struct Point) * size);
It's fine, because malloc only runs once.
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!
struct element {
unsigned long int ip;
int type;
int rtt;
struct element * next;
struct element * edge;
};
I have a linked list. I create new nodes using malloc.
I tried to free up memory using free (ptr to node)
but when I run the traverse function again, I can traverse the linked list and the rtt value is correct as well as the next and edge pointers as I can follow the linked list. ONly the ip value is corrupted. why is this?
The behaviour of malloc() and free() depends heavily on the operating system and C library that you are using. In most implementations there are actually two memory allocators in play:
The OS memory allocator, which uses the virtual memory facilities of the processor to provide a process with its own address space and maps physical memory pages into that address space for use.
The C library memory allocator, which is in fact part of the application code and uses the pages provided by the OS to provide fine-grained memory management facilities, as provided by malloc() and free().
In general, calling free() does one or more of the following:
It marks the pointed-to memory area as free in the C memory allocator. This allows that memory to be reused. free() does not zero-out freed memory.
It may return memory to the OS, depending on the settings of the C memory allocator and whether it is actually possible to free that part of the heap. If memory is not returned to the OS, it can be reused by future malloc() calls by the same application.
If you try to access memory that has been freed, usually one of three things will happen:
The memory has been returned to the OS, and your program, typically, crashes. If you ask me, that is probably the best scenario - you have a problem, sure, but you know it.
The memory has not been reused, therefore your old data is still there. Your program goes on as if nothing was wrong. This is in my opinion the worst case scenario. Your code appears to work correctly and, if Murphy has a say in this, it will continue to do so until it reaches your end users - then it will fail spectacularly.
The memory has been reused by your program, and your code will start messing around with its own data. If you are careful (and lucky?), you will probably notice that the results are off. If not, well...
If you are on Linux/Unix Valgrind is a good tool to catch memory management problems like this. There are also replacement libraries for the C memory allocator, such as DUMA that will also allow you to detect such issues.
Memory is not wiped when you free it - that would be a waste of processor time. It is just allocated to the "free list". That is why your data is still there
Whenever you free a block, you should set the corresponding pointer to NULL, so you don't accidentally reference it - it could be reused at any time.
Actually free doesn't delete anything, it just tells the OS it can use that memory again, for example next time you call malloc() it could overwrite some of your nodes.
Freeing the memory releases it for reuse. It doesn't necessarily destroy the data that was at that location. It is up to you not to access a memory region that has been released because the behavior is undefined (i.e. usually very bad).
If you want the data destroyed for some strange reason, then overwrite the memory area prior to freeing it (e.g. memset(buf, 0, len)).