For the code below: (1) \"main\" calls a function \"f1\". (2) function \"f1\" does some number crunching; creates an array of \"char\" with mal
I assume, although the function "f1" has terminated, the allocated char array still stays allocated until the main program terminates completely.
True. Dynamically allocated memory has nothing to do with functions, it belongs to process.
That is, the allocated memory still belongs to the main and no other process can access it from outside. Am I right?
Memory doesn't belong to main()
(intended as function) but to process itself (of which main()
is just the entry point). In a system with memory protection (where each process is isolated from the others) it's not accessible from outside. You can, however, allocate it in a system specific way to share memory across processes.
Do I have to free the array (allocated in "f1") before the program terminates (or does it get freed as soon as the main program terminates) ?
Yes. Unallocated memory - in most systems - is automatically deallocated by Operating System when process terminates but this is system dependant. IMO even when OS does it you should always deallocate, using such automatic deallocation as a red flag (I forget that to deallocate, is it a bug? something I missed?). Moreover if f1
is invoked 1000 times it'll leak memory each time quickly eating all available memory. Think about a process in a server, it may (and should) be up and running for years.
If the answer for the second question is "yes" then how do you free an array allocated in another function?
It's nice when who allocates memory also frees it. If it's not possible then caller will become responsible for such memory. It's, for example, what strdup()
does. In such case called function must return (somehow) a pointer to allocated memory (or an handle/token that can be used by another specialized function). For example:
char* pBuffer = f1();
// Use it
free(pBuffer);
Note that there are many many techniques if you want to hide such internal pointer. You may use a token (for example an integer, key in a dictionary), a typedef
or an opaque type.
malloc
allocates memory on heap and therefore this memory remains allocated until it is freed by free
function or program terminate successfully.
In your case you freed ftemp
in f1
so it is no longer exist after function terminates. fdata
is still on heap and it is accessible to main
as you are returning pointer to that allocated location.
Once main
terminates successfully, memory pointed by fdata
get freed.
So, it's considered good to free memory as soon as you don't need it any more. There is no point in freeing blocks at the end of a program, because all of the program's space is given back to the system when the process terminates (considering modern operating systems).
Using malloc
will allocate memory on the heap until it you free
it.
This means you need to assure every malloc has a corresponding free, also it is not implied that no other process can't access your data. It's just a value at an address.
In your main you must free(fData)
to avoid a memory leak.
To sum up then:
1) Your first assumption is correct, the second and third is not. It will stay allocated, but it's not local to the main, and not bound to the process as it terminates.
2) Yes, you must free it
3) Use the pointer you get from the function. If you do not return a pointer to your allocated data from a function, make sure that function free
s it.
Yes, it's still in the heap. However, you are confusing about the concept of process. Unless you create another process (using fork
on *nix), it's still the same process.
It's a good habit to free the memory when it's not used. But if the program terminates normally, the allocated memory is freed by the system.
Like this:
int main () {
char *fData = f1 (...);
//...
free(fData);
//...
}
There are two basic types of memory you can work with in C. The two types are the stack and the heap. In general, the variables you create within a function will be allocated on the stack and will be freed when the function returns. Memory allocated in the heap will persist and you are obligated to manage that allocation within your program. Memory in the heap will remain allocated until you free is up using the pointer (memory address) that refers to the data block.
A little reading on both will help you understand. I'd point out that you have two instances of fData, each with their own scope. Both pointers point to the memory you allocate with:
char *fData = malloc (length2 * sizeof (char));
.. even though they pass in and out of scope as your code executes.
If you don't free memory you're not using, eventually this would accumulate- if you done this with many other pointers- and your program could run out of memory. After freeing a memory block using the free
function, I'd also suggest assigning NULL
to the pointer as this protects against dangling pointers as even if you've freed a pointer, if you try accessing it, you could get undefined behaviour, whereas access and operations on NULL
pointers result in a crash, so you'd easily be able to trace the problem