Hi Stack Overflow Community. I am very new to C programming and have begun learning about dynamic allocation. In every code example I have come across, memory is freed using free() within the function the memory is allocated too. I wanted to know if it is possible to free() dynamically allocated memory outside of the function in which you allocate memory. For example, here is a piece of code that does that:
Will this freeing of memory outside of the function cause memory leak? or is this ok. A followup question I had to this would be if it is possible to access this memory in the main function (where I print the results) without using dynamically allocated memory? For example could I use a global array and modify it in the ret function instead?
CodePudding user response:
Please don't post images of code. Just copy-paste it in the post.
Well, to answer your question, you could do that. By the time you have the pointer that is dynamically allocated, you can.
To your second question, yes you could do that as well.
CodePudding user response:
Yes, you can. If you dynamically allocate memory inside of an "external function" (meaning, in this case, a function that is not main
), chances are that it's because you want to use that data once the execution of the function's body has come to an end. You just return a pointer of type int
(I think that it wouldn't be possible if the allocated memory was automatically freed, it wouldn't make sense).
You can always free it later in the main
using free(ptr);
.
You could also use an array but you couldn't free it because you can only use free
to release dynamically allocated memory.
CodePudding user response:
I wanted to know if it is possible to free() dynamically allocated memory outside of the function in which you allocate memory.
Of course, you can. The heap manager has no idea which function called calloc
. So, why would it care which function called free
?
As long as for every alloc (malloc/calloc/realloc
) you [eventually] do a free
you're fine. Which functions make these calls doesn't matter.
A "memory leak" is when you allocate memory but never free it (by any means or function)
Some code will best illustrate this along with showing the various ways to free the memory with respect to "who" frees it:
void
do_stuff(void *ptr)
{
// do stuff with ptr ...
}
void
do_stuff_free(void *ptr)
{
// do stuff with ptr ...
free(ptr);
}
void
leaker(void)
{
void *ptr;
// this leaks memory
while (1) {
ptr = malloc(1);
do_stuff(ptr);
}
}
void
noleaker(void)
{
void *ptr;
// this does _not_ leak memory
while (1) {
ptr = malloc(1);
do_stuff(ptr);
free(ptr);
}
}
void *
alloc_something(void)
{
void *ptr;
ptr = malloc(1);
return ptr;
}
void
noleaker2(void)
{
void *ptr;
// this does _not_ leak memory
while (1) {
ptr = alloc_something();
do_stuff_free(ptr);
}
}
A followup question I had to this would be if it is possible to access this memory in the main function (where I print the results) without using dynamically allocated memory? For example could I use a global array and modify it in the ret function instead?
Yes, of course. If you have a global memory scope array, any function may read/modify it and any function may see the results of that modification.
If you have an "outer" scope local array (e.g. one defined in main
). That can be passed to any called function.
But, a local scope array can not be returned (as a pointer) to a caller
Here's some examples:
#include <stdio.h>
#define COUNTOF(_arr) \
(sizeof(_arr) / sizeof(_arr[0]))
int glob_array[10] = { 0 };
void
change_glob(void)
{
glob_array[3] = 7;
}
void
change_array(int *arr)
{
arr[2] = 23;
}
void
show_array(const int *arr,size_t size)
{
for (int idx = 0; idx < size; idx)
printf(" %d",arr[idx]);
printf("\n");
}
void
show_glob(void)
{
show_array(glob_array,COUNTOF(glob_array));
}
int *
return_local(void)
{
int array[10] = { 0 };
// this is _invalid_ -- it goes out of scope before caller can use it
// this is flagged by the compiler: -Wreturn-local-addr
return array;
}
int
main(void)
{
int local_array[10] = { 0 };
change_glob();
show_glob();
change_array(local_array);
show_array(local_array,COUNTOF(local_array));
return 0;
}