When I alloc memory outside a while loop for example, is it okay to free it inside it ?
Are these two codes equivalent ?
int* memory = NULL;
memory = malloc(sizeof(int));
if (memory != NULL)
{
memory=10;
free(memory);
}
int* memory = NULL;
memory = malloc(sizeof(int));
if (memory != NULL)
{
memory=10;
}
free(memory);
Yes, they are equivalent. You do not have to call free() if allocation did not succeed.Pay attention, that memory is pointer to int and you have to dereference it to assign something to its memory block;
int* memory = NULL;
memory = malloc(sizeof(int));
if (memory)
*memory=10;
free(memory);
memory = NULL;
int* memory = NULL;
memory = malloc(sizeof(int));
if (memory != NULL)
{
memory=10;
free(memory);
}
This will crash. You're setting the pointer to memory location 10 and then asking the system to release the memory. It's extremely unlikely that you previously allocated some memory that happened to start at 10 (0xA in hexadecimal), even in the crazy world of virtual address spaces. Furthermore, IF malloc failed, no memory has been allocated, so you do not need to free it.
int* memory = NULL;
memory = malloc(sizeof(int));
if (memory != NULL)
{
memory=10;
}
free(memory);
This is also a bug. If malloc fails, then you are setting the pointer to 10 and freeing that memory. (as before.) If malloc succeeds, then you're immediately freeing the memory, which means it was pointless to allocate it! Now, I imagine this is just example code simplified to get the point across, and that this isn't present in your real program? :)
Doesn't matter IF you are sure you only free it once.
A good idea is to always set a pointer =NULL when you free it, then if it gets free'ed again it won't matter
Yes. The important thing is too free it once. (After you are finished using the memory)
A general rule of thumb that I like to follow is to free memory in the same scope that it was allocated in.
First of all you can only free it once. So if you want to free it inside a loop (as your question suggest), the second solution is the only correct way of doing.
If you want to free it inside an if statement, both solution are technically correct. However it is a good practice to always free the memory you use and its then easier to always free the memory at the end outside any if statement.
So my advice is : whatever you are trying to do : always free the memory outside any loop/if statement (assuming you don't need it anymore of course). I usually free it at the end of the function where it's last used but it really depends on the function itself, its length, ....
Try finding your way of doing things and stick to it : it will save you a lot of useless brain time (which is really precious)
Related
I'm starting to learn C programming and stumbled upon a situation that shows my lack of understanding of how memory allocation with malloc() works.
In a loop like the following:
// will only know `xlen` at runtime so I guess I have to use malloc here
char *x = malloc((xlen + 1) * sizeof(*x));
assert(x != NULL); // memory allocation failed
while (fgets(line, sizeof(line), fp) != NULL) {
strncpy(x, line, xlen); // copy first xlen characters of line
x[xlen] = '\0'; // ensure null terminating string
// do something with x
// x can now be "reused" for another line/loop iteration
// free(x) - errors out with "pointer being freed was not allocated"
}
fclose(fp)
free(x);
If the statement free(x) is called inside the loop then when I run this program I get an error message something like a.out(37575,0x7fff964ce3c0) malloc: *** error for object 0x7fab47c02630: pointer being freed was not allocated.
Why am I seeing this error message and what is causing it?
Will the memory address block of x be "re-used" at each iteration of the loop? (I'd say yes, and that would actually be what I wanted in this case) In this case, is it safe to only free the allocated memory of x outside the scope of the loop?
free(x); frees the memory allocated by char *x = malloc(.... It frees all of the memory, and you don't have to worry about how much memory that was, as it keeps track of that. You just have to call free(x); once as you correctly do. This is why you get the error if you free it inside the loop.
Does it mean that the memory address block of x will be "re-used" at
each iteration? (I'd say yes, and that would actually be what I wanted
in this case)
Yes, you use the same memory. It overwrites the memory every time.
In this case, is it safe to only free the allocated memory of x
outside the loop scope?
Yes, you have to free it outside of the loop. Because if you free it, then all of it is freed. If you did that inside the loop, then it would be undefined behavior to keep accessing that memory in following loop iterations.
The malloc() function provides a pointer to an area of memory that can then be used just like any pointer to a memory location.
The way to think of malloc() and free() is to consider it in terms of who owns a memory area. The malloc() function owns the memory that it is managing. When you call the malloc() function, or calloc() function, the function takes some of the memory it is managing and transfers ownership to you. When the function is called and the memory allocated there is a transfer of ownership from the memory management system of malloc() to you and at that point you own that memory and it is up to you to manage it. When the free() function is called to release the memory, you are transferring ownership of the memory area from you back to the memory management system of malloc().
Whenever a transfer of ownership is done, the entity that is giving up ownership is not supposed to do anything further with the memory area since it no longer owns it.
So when you do the malloc() you now own the memory and can use and reuse the memory area as much or as little as you want until such time that you call the free() function to give it back to malloc().
A pointer to a memory region given by malloc() is like any other pointer so far as using it is concerned.
Once you have transferred ownership of a memory area back to malloc() by using thee free() function, you can't call free() again with the same pointer without introducing an error. Once a memory area has been returned using free() you no longer have ownership of the memory so you shouldn't try to do anything else with it and that includes calling free() with the pointer again.
How malloc() manages memory is an implementation detail that will vary depending on the compiler and the C Runtime used. In some cases if you malloc() memory then free() the memory and then malloc() the same amount of memory again you may get lucky and get the same memory area again however it is not something you can count on or should expect.
malloc() provides you a pointer to a memory area that has a couple of guarantees. First of all the memory area provided will be at least as large as you requested. It may be larger but it won't be smaller than what you requested. Secondly the address provided will be on a memory boundary suitable for the machine architecture so that you can use the address provided for any variable type whether a built in such as int or double or a struct or an array of some type.
As the owner of the memory area provided by malloc() you are responsible for giving the memory area back to the malloc() functionality once you are done with it.
Your other primary responsibility is to respect the size of the memory area and to not write a larger data block into the area than the size requested when the malloc() was done. You are guaranteed only the amount of memory requested and writing a larger block of data into the memory will probably overwrite memory that you do not own but is owned by something else.
Unfortunately because the malloc() functionality, at least the optimized or non-debug version of the library, is designed with little as possible overhead, the functionality has few consistency and sanity checks in place. The malloc() functionality trusts that you will obey the rules and guidelines and only use what you own. And often when you break the rules and guidelines, you won't see the effect at the point where you have made a mistake but rather at some other point when some mysterious memory corruption is discovered and your program crashes.
You can use and reuse dynamically allocated memory as long as you have not called free() on it. If you free it and attempt to use it again, then you will have undefined behaviour.
You can continue to reusing memory (eg buf created by char *buf = calloc(sizeOfBuf); ) allocated to you on a single call to calloc(), until free(buf) is called, just as if buf was created statically, eg char buf[sizeOfBuf]; = 0. However, if the size of the buffer initially created by using calloc() needs to change, realloc() is available to do this, and is the preferable method. There are some caveats about using realloc however. Here is an example of using realloc, this one packaged into a function that resizes an existing dynamically allocated buffer, and takes care of some of the caveats:
realloc usage example:
// initial call to calloc
char *buf = calloc(sizeOfBuf);
if(buf)
{
while(someConditionIsTrue)
{
// read new content
//...
//new content needs to be added to buf
char *tmp = realloc(buf, newSizeOfBuffer);
if(!tmp)//if failed...
{
free(buf);//... free original buf to prevent memory loss
return NULL;// return null, caller must test for this
}
buf = tmp;//...else copy new mem location back to original pointer
//continue doing stuff with buf
}
//when done with buf, free it
free(buf);
}
One other suggestion, consider calloc() returns uninitialized memory, i.e. you own a space that contains whatever was occupying it when it was given to you. It is a good idea to follow that command with a method to clean up the buffer:
memset(buf, 0, sizeOfBuf);
Or use calloc().
int a = 0;
int *b = malloc (sizeof(int));
b = malloc (sizeof(int));
The above code is bad because it allocates memory on the heap and then doesn't free it, meaning you lose access to it. But you also created 'a' and never used it, so you also allocated memory on the stack, which isn't freed until the scope ends.
So why is it bad practice to not free memory on the heap but okay for memory on the stack to not be freed (until the scope ends)?
Note: I know that memory on the stack can't be freed, I want to know why its not considered bad.
The stack memory will get released automatically when the scope ends. The memory allocated on the heap will remain occupied unless you release it explicitly. As an example:
void foo(void) {
int a = 0;
void *b = malloc(1000);
}
for (int i=0; i<1000; i++) {
foo();
}
Running this code will decrease the available memory by 1000*1000 bytes required by b, whereas the memory required by a will always get released automatically when you return from the foo call.
Simple: Because you'll leak memory. And memory leaks are bad. Leaks: bad, free: good.
When calling malloc or calloc, or indeed any *alloc function, you're claiming a chunk of memory (the size of which is defined by the arguments passed to the allocating function).
Unlike stack variables, which reside in a portion of memory the program has, sort of, free reign over, the same rules don't apply to heap memory. You may need to allocate heap memory for any number of reasons: the stack isn't big enough, you need an array of pointers, but have no way of knowing how big this array will need to be at compile time, you need to share some chunk of memory (threading nightmares), a struct that requires the members to be set at various places (functions) in your program...
Some of these reasons, by their very nature, imply that the memory can't be freed as soon as pointer to that memory goes out of scope. Another pointer might still be around, in another scope, that points to the same block of memory.
There is, though, as mentioned in one of the comments, a slight drawback to this: heap memory requires not just more awareness on the programmers part, but it's also more expensive, and slower than working on the stack.
So some rules of thumb are:
You claimed the memory, so you take care of it... you make sure it's freed when you're done playing around with it.
Don't use heap memory without a valid reason. Avoiding stack overflow, for example, is a valid reason.
Anyway,
Some examples:
Stack overflow:
#include <stdio.h>
int main()
{
int foo[2000000000];//stack overflow, array is too large!
return 0;
}
So, here we've depleted the stack, we need to allocate the memory on the heap:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *foo= malloc(2000000000*sizeof(int));//heap is bigger
if (foo == NULL)
{
fprintf(stderr, "But not big enough\n");
}
free(foo);//free claimed memory
return 0;
}
Or, an example of an array, whose length depends on user input:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *arr = NULL;//null pointer
int arrLen;
scanf("%d", &arrLen);
arr = malloc(arrLen * sizeof(int));
if (arr == NULL)
{
fprintf(stderr, "Not enough heap-mem for %d ints\n", arrLen);
exit ( EXIT_FAILURE);
}
//do stuff
free(arr);
return 0;
}
And so the list goes on... Another case where malloc or calloc is useful: An array of strings, that all might vary in size. Compare:
char str_array[20][100];
In this case str_array is an array of 20 char arrays (or strings), each 100 chars long. But what if 100 chars is the maximum you'll ever need, and on average, you'll only ever use 25 chars, or less?
You're writing in C, because it's fast and your program won't use any more resources than it actually needs? Then this isn't what you actually want to be doing. More likely, you want:
char *str_array[20];
for (int i=0;i<20;++i) str_array[i] = malloc((someInt+i)*sizeof(int));
Now each element in the str_array has exactly the amount of memory I need allocated too it. That's just way more clean. However, in this case calling free(str_array) won't cut it. Another rule of thumb is: Each alloc call has to have a free call to match it, so deallocating this memory looks like this:
for (i=0;i<20;++i) free(str_array[i]);
Note:
Dynamically allocated memory isn't the only cause for mem-leaks. It has to be said. If you read a file, opening a file pointer using fopen, but failing to close that file (fclose) will cause a leak, too:
int main()
{//LEAK!!
FILE *fp = fopen("some_file.txt", "w");
if (fp == NULL) exit(EXIT_FAILURE);
fwritef(fp, "%s\n", "I was written in a buggy program");
return 0;
}
Will compile and run just fine, but it will contain a leak, that is easily plugged (and it should be plugged) by adding just one line:
int main()
{//OK
FILE *fp = fopen("some_file.txt", "w");
if (fp == NULL) exit(EXIT_FAILURE);
fwritef(fp, "%s\n", "I was written in a bug-free(?) program");
fclose(fp);
return 0;
}
As an asside: if the scope is really long, chances are you're trying to cram too much into a single function. Even so, if you're not: you can free up claimed memory at any point, it needn't be the end of the current scope:
_Bool some_long_f()
{
int *foo = malloc(2000000000*sizeof(int));
if (foo == NULL) exit(EXIT_FAILURE);
//do stuff with foo
free(foo);
//do more stuff
//and some more
//...
//and more
return true;
}
Because stack and heap, mentioned many times in the other answers, are sometimes misunderstood terms, even amongst C programmers, Here is a great conversation discussing that topic....
So why is it bad practice to not free memory on the heap but okay for memory on the stack to not be freed (until the scope ends)?
Memory on the stack, such as memory allocated to automatic variables, will be automatically freed upon exiting the scope in which they were created.
whether scope means global file, or function, or within a block ( {...} ) within a function.
But memory on the heap, such as that created using malloc(), calloc(), or even fopen() allocate memory resources that will not be made available to any other purpose until you explicity free them using free(), or fclose()
To illustrate why it is bad practice to allocate memory without freeing it, consider what would happen if an application were designed to run autonomously for very long time, say that application was used in the PID loop controlling the cruise control on your car. And, in that application there was un-freed memory, and that after 3 hours of running, the memory available in the microprocessor is exhausted, causing the PID to suddenly rail. "Ah!", you say, "This will never happen!" Yes, it does. (look here). (not exactly the same problem, but you get the idea)
If that word picture doesn't do the trick, then observe what happens when you run this application (with memory leaks) on your own PC. (at least view the graphic below to see what it did on mine)
Your computer will exhibit increasingly sluggish behavior until it eventually stops working. Likely, you will be required to re-boot to restore normal behavior.
(I would not recommend running it)
#include <ansi_c.h>
char *buf=0;
int main(void)
{
long long i;
char text[]="a;lskdddddddd;js;'";
buf = malloc(1000000);
strcat(buf, "a;lskdddddddd;js;dlkag;lkjsda;gkl;sdfja;klagj;aglkjaf;d");
i=1;
while(strlen(buf) < i*1000000)
{
strcat(buf,text);
if(strlen(buf) > (i*10000) -10)
{
i++;
buf = realloc(buf, 10000000*i);
}
}
return 0;
}
Memory usage after just 30 seconds of running this memory pig:
I guess that has to do with scope 'ending' really often (at the end of a function) meaning if you return from that function creating a and allocating b, you will have freed in a sense the memory taken by a, and lost for the remainder of the execution memory used by b
Try calling that function a a handful of times, and you'll soon exhaust all of your memory. This never happens with stack variables (except in the case of a defectuous recursion)
Memory for local variables automatically is reclaimed when the function is left (by resetting the frame pointer).
The problem is that memory you allocate on the heap never gets freed until your program ends, unless you explicitly free it. That means every time you allocate more heap memory, you reduce available memory more and more, until eventually your program runs out (in theory).
Stack memory is different because it's laid-out and used in a predictable pattern, as determined by the compiler. It expands as needed for a given block, then contracts when the block ends.
So why is it bad practice to not free memory on the heap but okay for memory on the stack to not be freed (until the scope ends)?
Imagine the following:
while ( some_condition() )
{
int x;
char *foo = malloc( sizeof *foo * N );
// do something interesting with x and foo
}
Both x and foo are auto ("stack") variables. Logically speaking, a new instance for each is created and destroyed in each loop iteration1; no matter how many times this loop runs, the program will only allocate enough memory for a single instance of each.
However, each time through the loop, N bytes are allocated from the heap, and the address of those bytes is written to foo. Even though the variable foo ceases to exist at the end of the loop, that heap memory remains allocated, and now you can't free it because you've lost the reference to it. So each time the loop runs, another N bytes of heap memory is allocated. Over time, you run out of heap memory, which may cause your code to crash, or even cause a kernel panic depending on the platform. Even before then, you may see degraded performance in your code or other processes running on the same machine.
For long-running processes like Web servers, this is deadly. You always want to make sure you clean up after yourself. Stack-based variables are cleaned up for you, but you're responsible for cleaning up the heap after you're done.
1. In practice, this (usually) isn't the case; if you look at the generated machine code, you'll (usually) see the stack space allocated for x and foo at function entry. Usually, space for all local variables (regardless of their scope within the function) is allocated at once.
I've read conflicting information on the internet about this. To the best of my knowledge all variables in a function only exist for the life time of the function and so this shouldn't be necessary. But with dynamic pointer arrays I'm not sure.
Thanks
You don't free pointers - they are cleaned up automatically. What you need to free is the memory that was acquired by malloc. You use pointers to access that memory.
Put laconically: Every pointer you get from malloc has to go to free exactly once. Nothing more, nothing less.
It depends on where the memory referenced by the pointer has been allocated.
There are fundamentally 2 ways of allocating space in C.
Using the stack :
void foo(){
int stack_variable = 10;
int *stack_pointer = &stack_variable; //bar shouldn't be freed.
}
Using the heap:
void foo(){
int * heap_pointer = (int *) malloc(sizeof(int)); //heap_pointer need to be freed somewhere
}
In the first case there is no problem: memory allocated in the stack will be released when the function returns. Even if you are using a pointer, and it points to some data in the stack, free isn't necessary. Be careful to not use a pointer to data allocated in the stack when the data itself goes out of scope:
int * foo(){
int stack_variable = 10;
int *ptr = &stack_variable;
return ptr;
}
int * ptr = foo(); // you have a problem here: ptr points to a memory region that no longer exist!
In the second case you are using the heap so you need to use free somewhere, to explicitly release it.
If you have allocated data using malloc/calloc, you need to free the data.
Addition due to curious comment by #Julia Childe:
Well, the point of allocating dynamic memory is that it will remain there till you explicitly free it. This enables you to pass pointers both from and to functions and you are not limited by the scope of a specific function, i.e. main.
Thereby, you can allocate memory for data when you need to and not in advance, thus dynamic memory.
If we did not have this ability, we would have to know how much memory space we would use at compile time.
Hope this clears out some question marks.
#include<stdio.h>
#include<stdlib.h>
int main()
{
char *temp;
while(1)
{
temp= malloc(sizeof(char)*10);
/*some code*/
}
}
My question is: I was allocating memory in every loop with same name. What will happen to previous memory allocated; and as we are creating variables with same identifier why we are not getting any errors?
PS: Don't ask what I'm doing in this code. I was doing some other code and by mistake did it. Just re modified it and asking my problem .
It's called a memory leak. You have no way of ever freeing the memory, so it's lost to you.
Your process will keep growing in size until you run out of available memory (or, if it's 64 bit, swap the box into oblivion at which point your local sysadmin will come over and trounce you. If it's a production machine, you're likely to find out what a performance improvement plan is from your boss and HR.)
what will happen to prev memory allocated.
Will be lost forever. That is what is called "memory leak".
and as we are creating variables with same identifier why we are not getting any errors
That's not a compilation error. The compiler doesn't follow your logic, only your syntax. Overwriting values is perfectly fine with the compiler.
The previos memory allocated will be leaked, since its not freed and its address gets lost to the program. You don't get any errors because you are not creating variables with the same identifier, you are allocating different chunks of memory and storing the pointer to them into the same temp variable.
Consider reading some basic C programming material as you seem to be confusing variables with memory.
The compiler will in most cases not detect logical errors, such as this, where the programmer allocates memory but never frees it.
This is what we call a "memory leak".
Here temp is a pointer not an identifier.
So temp POINTS to the memory allocated my malloc.
So when you allocate new memory and use the SAME pointer to point to the newly allocated memory, it NO LONGER points the the old allocated memory block and it is lost forever. So there you have a memory leak.
If you no longer need the memory pointed to by temp after the end of the current iteration of the loop, use following code instead.
#include<stdio.h>
#include<stdlib.h>
int main()
{
char *temp;
while(1)
{
temp= malloc(sizeof(char)*10);
/*some code*/
/* free the memory pointed by temp */
free(temp);
}
}
This way you do not have a memory leak as the memory pointed to my temp is freed at the end of the iteration before a new block is allocated at the start of the next loop.
Update:
Also you can use the same memory block pointed to by temp throughout your loop. No need to reallocate in each iteration.
And if you do not want to retain any old memory you can simply use memset, like this
#include<stdio.h>
#include<stdlib.h>
int main()
{
/* allocate memopry only once */
char *temp = malloc(sizeof(char)*10);
while(1){
/* zero out the memory so no old data is left */
memset((void*)temp, 0, sizeof(char)*10);
/* some code that uses temp */
}
/* free the allocated memory */
free(temp);
}
Could somebody tell me the difference between:
int *p;
p=(int*)malloc(10*sizeof(int));
free(p);
or
int *p;
p=(int*)malloc(10*sizeof(int));
p=NULL;
free will deallocate the memory that p points to - simply assigning it to NULL will not (and thus you will have a memory leak).
It is worth mentioning that it is good practice to assign your pointer to NULL AFTER the call to free, as this will prevent you from accidentally trying to access the freed memory (which is still possible, but absolutely should not be done).
There is no garbage collection in C, so if you don't explicitly free a chunk of memory, it will never get freed, even if there are no references to it. Maybe you come from a background in garbage collected languages, so it might be hard to change your way of thought, but it's always important to remember to "manually" free all resources in low-level languages like C.
Hope this helps
Cheers
p is pointer (to a block allocated dynamically in memory ["on the Heap"])
This means that p is a variable which contains the address in memory of a particular block (or some particular size, in the example a block big enough to hold 10 integers).
free(p); instructs the memory management logic (of the C Runtime) that the memory previously occupied by the block which p points to can be reused.
p = NULL; sets the value of p to NULL (the address it formerly contained is lost) but the block in memory it pointed too is still considered in use.
There can be some confusion because in languages such as Java, C#, Python etc. merely assigning the variable to NULL (or to another address for that matter), will automatically free the underlying memory (assuming no other references to this address exist in other live variables).
This is not the case in C or C++, leading to errors like the following:
free(p);
// possibly some some code etc.
// later:
p[6] = 'a'; // <<--- Ouch we're modifying whatever new variable is there !!!
or
// didn't call free(p)
p = NULL;
// now the memory allocated for p is held in memory even though it
// is not going to be used (assuming no copies of p or of pointers to part
// of that block were made.
The latter case is only wasteful of resources, the former can lead to hard to find bugs.
That's why a typical C idiom is:
free(p);
p = NULL;
Not calling free and directly assigning to NULL will lead to a memory leak as explained by others. You can refer to this link to get clear details about memory leaks and other memory related problems.
The better way is to first free the memory and then set it to NULL:
free(p);
p = NULL;
Freeing the allocated memory deallocates it and allows that memory to be used elsewhere while the pointer to where the memory was allocated is preserved.
Setting a pointer to the allocated memory to NULL does not deallocate it.
If you are using an implementation that uses a heap-based malloc, debug something that allocates, uses and frees memory, and do the same to something that allocates, uses, and sets the pointer to the memory to NULL.
Memory management is implementation-dependent (see http://en.wikipedia.org/wiki/Malloc#Implementations).
1.
int *p;
p= (int * ) malloc(10*sizeof(int));
free(p);
the memory is released back to the heap. but the pointer still pointing to the freed memory location. Thus if its further used , would lead to a memory corruption.
thus correct thing to do is resetting the pointer to NULL explicitly to avoid further usage of that pointer .
its not advisable to type cast the return pointer in C
2.
int *p;
p=(int * )malloc(10*sizeof(int));
p=NULL;
This would result in a memory leak : as the allocated memory is not freed here. you are just reset the pointer to NULL.
p=NULL does not deallocate the memory. If you don't need to use the memory pointed by p anymore you should use free() otherwise there will be memory leak. You should also set p=NULL after calling free() to avoid erroneously accessing that memory again in the future.