Reputation: 1941
I have several methods in my program where I have a char *str, which I malloc, and then need to return str at the end of the method. I'm at a loss on where I need to put the free() statement in these methods. If I free() before I return str, the str is empty, and if I do it after the return statement, it won't be freed at the right time I guess? If i e.g. exit the program before it is freed, this will create memory leaks. What is the correct way to do this?
Upvotes: 3
Views: 4353
Reputation: 153348
In the highest level function that uses the allocated memory, call free()
to release the memory.
After free-ing, setting the value to NULL
insures subsequent usage of s
does not use free'd memory. If the variable is not subsequently accessed, then the unneeded s = NULL;
will likely get optimized out by the compiler.
char *Allocator() {
...
char *s = malloc(...);
...
return s;
}
void foo() {
...
char *s = Allocator;
// ... use s
free(s);
s = NULL;
...
}
Upvotes: 0
Reputation: 1682
From reading your question, I think you have a wrong understanding on how malloc and free works.
Malloc will allocate space on the heap of your process. This heap is global, meaning that you can access it from anywhere in your code (and not just in your function). Thus, you can also free it anywhere in your code. If you return a pointer to allocated space, it makes no sense to free it in the same function (otherwise you have a dangling pointer, i.e. a pointer that referes to already freed space). So it is perfectly fine (and neccessary) to free your pointer from anywhere else but your function.
Also, you don't have a memory leak "after" your process exits, as you stated. Memory leaks occur inside processes; meaning that some heap of the process is allocated, but not used anymore (and there's no reference to it so it can't get freed anymore). when your program takes a lot of space on the heap, this can lead to out of memory problems (and also it's not good for performance anway, so you never want that to happen). When your process exits however, all of it's memory (including he heap) gets deallocated anyway by the OS. So, there's no memory leak anymore (except maybe when you're dealing with mutlithreading, but that's a different topic).
Upvotes: 5
Reputation: 1286
There are plenty alternatives for that problem, here are some solutions:
1- Use a function to allocate and another to free as Bill Lynch post in his answer. This is normaly used when you are using structures with good practises (you create a constructor and a destructor).
2- The person who uses the function is responsible to free the string it returns.
3- You can pass the return value as an argument, here's an example:
void foo(char* s) {
snprintf(s, 10, "hello");
}
Note that this last solution is frequently used when you want to return an exit code saying that everything went write (you'll find many functions using this).
int foo(char* s) {
snprintf(s, 10, "hello");
return 1; // everything went well
}
Upvotes: 0
Reputation: 333
It dosnt really matter where you free your allocated memory, as long as you do not forget to free it. In my opinion, the best place to put the free()'s are right before the return from the function, in a label called cleanup. That way, you will not have memory leaks, because if you make sure at every function that you do not have memory leaks, your entire program will not have memory leaks.
Your functions should look somethinhg like this:
int func(void)
{
/* Code that has allocations in it */
cleanup:
/* Here you should free all of your allocations */
return 0;
}
If you are using Linux, you can use valgrind in order to make sure you do not have any memory leaks.
Upvotes: 0
Reputation: 50776
You must free the buffer when you don't need it's content anymore and not before.
Your pattern it like this:
char *SomeFunction()
{
...
return malloc(somelength) ;
}
...
char *mychar = SomeFunction() ;
... // deal with the mychar buffer
free(mychar);
...
Upvotes: 1
Reputation: 81926
I'm often pretty happy if I can make my code follow this pattern:
char * foo_allocate() {
char * s = malloc(10);
snprintf(s, 10, "hello");
return s;
}
void foo_release(char *s) {
free(s);
}
Upvotes: 2