Basic C pointer allocation/deallocation - c

Writing code in C, never formally learned any of it, using GNU's GSL library, quick fundamental question.
Correct me if I'm wrong, but the way I understand it, when I allocate memory to use for my matrices (using the built-in var = gsl_matrix_alloc(x,x)) and store them in a variable, I'm essentially creating
a pointer, which is simply some address of memory, like:
x01234749162
which POINTS to the first pointer/memory location of my GSL matrix. Tracking when to deallocate the memory of the structure associated with a pointer (again, built-in gsl_matrix_free(x,x,x)) is no problem, and I understand I need to do this before I reassign the pointer of the structure, otherwise I've created a memory leak.
So now to my question, and again, I know this is basic, but hear me out--I couldn't find a particularly straight answer on stackoverflow, mostly because a lot of the answers involve C++ rather than C--how do I free the pointer to the structure itself?
Everyone says "oh, just set it to NULL". Why would that work? That's just changing the memory address that POINTS to the deallocated structure. Does that tell the MMU that that memory location is okay to use now? When I debug my program in XCode, for example, all of the properties of the gsl_matrix structure is successfully deallocated; everything just becomes this garbage string of random hex characters, which is what free'ing memory is supposed to do. But, I can still see the variable name (pointer) while stepping through the debugger... even if I set the variable to NULL. I would interpret that as meaning I did not free the pointer, I just freed the structure and set it to x0000000 (NULL).
Am I doing everything correct, and this is just a feature of XCode, or am I missing something basic?
And I realize that a single pointer to a structure, if the structure is deallocated, could be argued to not be a big deal, but it matters.
Here's some code to try to illustrate my thoughts.
gsl_matrix* my_matrix;
// create single memory address in memory, not pointing to anything yet
my_matrix = gsl_matrix_alloc(5, 5);
// allocates 25 memory spaces for the values that the pointer held by my_matrix
// points too
// Note: so, now there's 26 memory spots allocated to the matrix, excluding other
// properties created along with the my-matrix structure, right?
gsl_matrix_free(my_matrix); // deallocates those 25 spaces the structure had,
// along with other properties that may have been automatically created
free(my_matrix); // SIGBRT error. Is the pointer to the deallocated structure
// still using that one memory address?
my_matrix = NULL; // this doesn't make sense to me.I get that any future referral
// to the my_matrix pointer will just return garbage, and so setting a pointer to
// that can help in debugging, but can the pointer--that is just one memory
// address--be completely deallocated such that in the debugger the variable name
// disappears?

What you miss here is the knowledge of how "local variables" work at the machine level and the concept of "the stack".
The stack is a block of free memory that is allocated for your program when it starts. Suppose, for the sake of a simple example, that your program is allocated a stack of size 1MB. The stack is accompanied with a special register, called "stack pointer", which initially points to the end of the stack (don't ask why not the beginning, historical reasons). Here's how it looks:
[---------- stack memory, all yours for taking ------------]
^
|
Stack pointer
Now suppose your program defines a bunch of variables in the main function, i.e. something like
int main() {
int x;
What this means is that when the main function is invoked at the start of your program, the compiler will generate the following instructions:
sp = sp - 4; // Decrement stack pointer
x_address = sp;
and remember (for purposes of further compilation) that x is now a 4-byte integer located at memory position x_address. Your stack now looks as follows:
[---------- stack memory, all yours for taking --------[-x--]
^
|
Stack pointer
Next, suppose you invoke some function f from within the main. Suppose f defines inside it another variable,
int f() {
char z[8];
Guess what happens now? Before entering f the compiler will perform:
sp = sp - 8;
z_address = sp;
I.e. you'll get:
[---------- stack memory, all yours for taking -[--z----][-x--]
^
|
Stack pointer
If you now invoke another function, the stack pointer will move deeper into the stack, "creating" more space for the local variables. Each time when you exit a function, though, the stack pointer is restored back to where it was before the function was invoked. E.g. after you exit f, your stack will be looking as follows:
[---------- stack memory, all yours for taking -[--z----][-x--]
^
|
Stack pointer
Note that the z array was not essentially freed, it is still there on the stack, but you do not care. Why don't you care? Because the whole stack is automatically deallocated when your application terminates. This is the reason why you do not need to manually deallocate "variables on the stack", i.e. those which are defined as local to your functions and modules. In particular, your my_matrix pointer is just a yet another variable like that.
PS: there is a bit more happening on the stack than I described. In particular, the stack pointer value is stored on the stack before decrementing it, so that it can be restored after exiting the function. In addition, function arguments are often passed by putting them onto the stack. In this sense they look like local variables for purposes of memory management and you don't need to free them.
PPS: In principle, the compiler is free to optimize your code (especially if you compile with the -O flag) and rather than allocate your local variables on the stack it may:
Decide to avoid allocating them at all (e.g. if they turn out to be useless)
Decide to allocate them temporarily in the registers (which are fixed memory slots in the processor that do not need to be freed). This is often done for loop variables (the ones within for (int i = ...)).
.. and well, do whatever else comes to his twisted mind as long as the result does not contradict the semantics.
PPPS: Now you are prepared to learn how buffer overflow works. Go read about it, really, it is an amazing trick. Oh, and, once you're at it, check out the meaning of stack overflow. ;)

Why would 26 memory spots be allocated for a 5x5 matrix? I'd say trust the library-provided gsl_matrix_free function to do the right thing and deallocate the whole structure.
In general, you only need to call free if you called malloc or calloc. Library functions that provide an allocator usually provide a matching deallocator so that you don't have to keep track of the internals.
If the 26th spot you're worried about is the pointer itself (in other words, the memory needed to store the address of the matrix), that space is part of the stack frame for your function, and it is automatically popped when the function returns.

Everyone says "oh, just set it to NULL". Why would that work?
They probably mean that this would fix the problem where you are calling free on a pointer to some data that has already been de-allocated, which is what you are doing here:
gsl_matrix_free(my_matrix); // deallocate
free(my_matrix); // Mistake, BIG PROBLEM: my_matrix points to de-allocated data
It fixes the problem because calling free on a null-ptr is a no op:
gsl_matrix_free(my_matrix); // deallocate
my_matrix = NULL;
free(my_matrix); // Mistake, but no problem
Note: my_matrix itself has automatic storage, so there is no need to de-allocate it manually. Its memory will be reclaimed when it goes out of scope. The only thing that needs to be de-allocated is the memory that was dynamically allocated (and to which my_matrix points.)

Related

Understanding C Memory Allocation and Deallocation

I have been recently trying to learn how to program in the C programming language.
I am currently having trouble understanding how memory is deallocated by free() in C.
What does it mean to free or release the memory?
For instance, if I have the following pointer:
int *p = malloc(sizeof(int));
When I deallocate it using free(p), what does it do? Does it somehow flag it as "deallocated", so the application may use it for new allocations?
Does it deallocates only the pointer address, or the address being pointed is also deallocated too?
I would do some experiments myself to better understand this, but I am so newbie in the subject that I don't know even how to debug a C program yet (I'm not using any IDE).
Also, what if int *p is actually a pointer to an array of int?
If I call free(p), does it deallocate the whole array or only the element it is pointing to?
I'm so eager to finally understand this, I would very much appreciate any help!
What does it mean to free or release the memory?
It means that you're done with the memory and are ready to give it back to the memory allocator.
When I deallocate it using free(p), what does it do?
The specifics are implementation dependent, but for a typical allocator it puts the block back on the free list. The allocator maintains a list of blocks that are available for use. When you ask for a chunk of memory (by calling malloc() or similar) the allocator finds an appropriate block in the list of free blocks, removes it (so it's no longer available), and gives you a pointer to the block. When you call free(), the process is reversed -- the block is put back on the free list and thereby becomes available to be allocated again.
Importantly, once you call free() on a pointer, you must not dereference that pointer again. A common source of memory-related errors is using a pointer after it has been freed. For that reason, some consider it a helpful practice to set a pointer to nil immediately after freeing it. Similarly, you should avoid calling free() on a pointer that you didn't originally get from the allocator (e.g. don't free a pointer to a local variable), and it's never a good idea to call free() twice on the same pointer.
Does it deallocates only the pointer address, or the address being pointed is also deallocated too?
When you request a block of memory from the allocator, you specify the size of the block you want. The allocator keeps track of the size of the block so that when you free the block, it knows both the starting address and the block size. When you call free(p), the block that p points to is deallocated; nothing happens to the pointer p itself.
Also, what if int *p is actually a pointer to an array of int?
An array in C is a contiguous block of memory, so a pointer to the first element of the array is also a pointer to the entire block. Freeing that block will properly deallocate the entire array.
I'm so eager to finally understand this, I would very much appreciate any help!
There are a number of good pages about memory allocation in C that you should read for a much more detailed understanding. One place you could start is with the GNU C Library manual section on memory allocation.
As alluded to above and in the other answers, the actual behavior of the allocator depends on the implementation. Your code shouldn't have any particular expectations about how memory allocation works beyond what's documented in the standard library, i.e. call malloc(), calloc(), etc. to get a block of memory, and call free() to give it back when you're done so that it can be reused.
malloc and free do whatever they want. Their expected behaviour is that malloc allocates a block of desired size in dynamic memory and returns a pointer to it. free must be able to receive one such pointer and correctly deallocate the block. How they keep track of the block size is irrelevant.
Is int *p a pointer to an array of ints ? Maybe. If you allocated sufficient space for several ints, yes.
There is a fixed and limited amount of memory in your computer, and everybody wants some. The Operating system is charged with the task of assigning ownership to pieces of memory and keeping track of it all to assure that no one messes with anyone else's.
When you ask for memory with malloc(), you're asking the system (the C runtime and the OS) to give you the address of a block of memory that is now yours. You are free to write to it and read from it at will, and the system promises that no one else will mess with it while you own it. When you de-allocate it with free(), nothing happens to the memory itself, it's just no longer yours. What happens to it is none of your business. The system may keep it around for future allocations, it may give it to some other process.
The details of how this happens vary from one system to another, but they really don't concern the programmer (unless you're the one writing the code for malloc/free). Just use the memory while it's yours, and keep your hands off while it's not.

How are char* deallocated in C

So I was reading through some code for a class and I am a little confused about how variable's are deallocated in C.
The code given is
#include<stdio.h>
main () {
int n=0;
char *p = "hello world";
while (*p!= 0) { // *p != '\0';
putc(*p, stdout);
p++;
}
printf("\np = %d", *p);
printf("\np = %d\n", p);
}
So i get that you don't need to free any memory for the char* since no mallocs are happening but i don't get why this code wouldn't leak any memory... If you are incrementing a pointer for a string and thus moving pointer to the next block of memory (1byte) then aren't you losing the initial reference and all reference points that you increment over? How would would this memory be reclaimed without a reference point, unless one is saved by the compiler before this type of operation occurs. I would appreciate some insight on how this is being reclaimed!
The task of deallocating memory is imposed on the owner of that memory. Just because you have a pointer to some memory region does not mean that you own that memory and, therefore, does not mean that you are responsible for deallocating it.
String literal "hello world" is an object with static storage duration. It is stored in static memory. Static memory is always owned by the runtime environment. The runtime environment is aware of data stored in static memory. The runtime environment knows when that data has to be deallocated (which is easy, since static memory is basically "never" deallocated - it exists as long as your program runs).
So, again, you with your pointer p do not really own any memory in static region. You just happen to refer to that memory with your p . It is not your business to worry about deallocation of that memory. It will be properly deallocated when the time comes (i.e. when the program ends) and it will be done properly without any help from you and your pointer p. You can change your p as much as you want, you can make it point to a completely different memory location, or you can discard it without any reservations. Speaking informally, nobody cares about your p.
The only memory you can possibly own in a C program is memory you personally allocated with malloc (or other dynamic memory allocation functions). So, you have to remember to eventually call free for the memory that you allocated yourself (and you have to make sure you know the original value returned by malloc to pass to that free). All other kinds of memory (like static or automatic) are never owned by you, meaning that freeing it is not your business and preserving the original pointer values is completely unnecessary.
You aren't leaking any memory because you are not dynamically allocating any memory. Memory leaks come from not freeing dynamically allocated memory. Locally allocated memory (like char *p) or statically allocated memory (like the string "hello world" that p initially points at) cannot contribute to leaks.
You are not dynamically allocating any new memory, hence you do not need to free it.
The string literal "hello world" is an object which is part of the program itself. When the "hello world" expression is evaluated, the program essentially obtains a pointer to a piece of itself. That memory cannot be deallocated while the program is running; that would be equivalent to making a "hole" in the program. The memory has the same lifetime as the program itself.
In the C language, the programmer is not required to manage memory which has the same lifetime as the program: this is externally managed (or mismanaged, as the case may be) by the environment which starts the program, and deals with the aftermath when the program terminates.
Of course, the memory still has to be managed; it's just that the responsibility does not lie with the C program. (At least, not in an environment which provides a hosted implementation of the C language. The rules for some embedded system might be otherwise!)
In a program that is embedded, the string literal (along with the rest of the program) could actually live in ROM. So there might really be nothing to clean up. The pointer is an address which refers to some permanent location on a chip (or several chips).
In short: because the program itself is short. You could be doing any malloc you want in there, and no leaks would actually happen, since all the memory is handed back to the OS as soon as the process ends. A leak would not be an issue in your example. Anyway,
in your case, a leak is not happening, because the variable p is pointing to a literal string, which is located in the data segment of the memory (i.e. it is a constant, written in the executable). This kind of memory cannot be de-allocated, because its space is fixed.
Actually, it is false that this is not a problem, because a very big executable, with lots of big constants in it, could have a remarkable memory footprint, but anyway this is not called a leak, because memory usage may be big, but it does not increase over time, which is the main point of a memory leak (hence the name leak).
When you declare your variables locally, the compiler knows how much space is required for each variable and when you run your program, each local variable (and also each function call) is put on stack. Just after return statement (or } bracket if void function) each local variable is popped from stack, so you don't have to free it.
When you call new operator (or malloc in pure C), the compiler doesn't know the size of the data, so the memory is allocated runtime on heap.
Why I'm explaining this is fact that whenever you call new or malloc (or calloc), it's your responsibility to free memory you don't want to use anymore.
In addition to the other answers, incrementing a pointer in C doesn't create or lose "references", nor does it cause any copying or other altering of the memory that the pointer points to. The pointer in this case is just a number that happens to point to a statically allocated area of memory.
Incrementing the pointer doesn't alter the bytes that the pointer used to point to. The "H", is still there. But the program now thinks that the string starts with "e". (It knows where the end of the string is because by convention strings in C end with a null.
There are no checks that the pointer points to what you think it should, or any valid area at all. The program itself could lose track of an area of memory (for instance if you set p=0), or increment p beyond the end of the string, but the compiler doesn't keep track of this (or prevent it), and it doesn't de-allocate the memory used for the string.
If you change the pointer to point to the "wrong" location in memory, fun (bad) things will happen - such as page faults, stack overflows and core dumps.

How is the destination that an uninitialized pointer in c points to determined?

I know that if a pointer is declared in C (and not initialized), it will be pointing to a "random" memory address which could contain anything.
How is where it actually points to determined though? Presumably it's not truly random, since this would be inefficient and illogical.
If this pointer is defined outside of all functions (or is static), it will be initialized to NULL before main() gets control.
If this pointer is created in the heap via malloc(sizeof(sometype*)), it will contain whatever happens to be at its location. It can be the data from the previously allocated and freed buffer of memory. Or it can be some old control information that malloc() and free() use to manage the lists of the free and allocated blocks. Or it can be garbage if the OS (if any) does not clear program's memory or if its system calls for memory allocation return uninitialized memory and so those can contain code/data from previously run programs or just some garbage that your RAM chips had when the system was powered on.
If this pointer is local to a function (and is not static), it will contain whatever has been at its place on the stack. Or if a CPU register is allocated to this pointer instead of a memory cell, it will contain whatever value the preceding instructions have left in this register.
So, it won't be totally random, but you rarely have full control here.
Uninitialized is undefined. Generally speaking, when the pointer is allocated the memory space is not cleared, so whatever the memory contained is now a pointer. It is random, but it is also efficient in the sense that the memory location is not being changed in the operation.
http://en.wikipedia.org/wiki/Uninitialized_variable
Languages such as C use stack space for variables, and the collection
of variables allocated for a subroutine is known as a stack frame.
While the computer will set aside the appropriate amount of space for
the stack frame, it usually does so simply by adjusting the value of
the stack pointer, and does not set the memory itself to any new state
(typically out of efficiency concerns). Therefore, whatever contents
of that memory at the time will appear as initial values of the
variables which occupy those addresses.
Although I would imagine this is implementation specific.
Furthermore you should probably always initialize your pointers, see the answer provided at How do you check for an invalid pointer? and the link given on the first answer: -
http://www.lysator.liu.se/c/c-faq/c-1.html
As far as the C standard is concerned, an uninitialized pointer doesn't point anywhere. It is illegal to dereference it. Thus it is impossible in principle to observe its target, and thus the target simply doesn't exist for all intents and purposes.
If you want a trite analogy, asking for the value of an uninitialized pointer is like asking for the value of the smallest positive real number, or the value of the last digit of π.
(The corolloary is that only Chuck Norris can dereference an uninitialized pointer.)
It is implementation specific / undefined behavior. It's possible the pointer was automatically initialized to NULL... or it is just whatever value is in memory at the time.
A pointer is an address in memory that points to another address in memory. The fact that it's not initialized does not mean that the pointer itself doesn't have an address, it only means that the address of the thing it points to is not known. So, either the compiler initialized it to NULL by default, or the address is whatever was in memory in the pointer's variable space at the time.
In large part, it is like an unerased whiteboard when you enter class. If you draw a box on part of the board but do not erase what is in the box, then what is in the box?
It is whatever was left there previously.
Similarly, if you allocate space for a pointer but do not erase the space, then what is in the space?
Data may be left over from earlier parts of your program or from special code that runs before any normal part of your program (such as the main function) starts running. (The special code may load and link certain libraries, set up a stack, and otherwise prepare the environment needed by a C program.) On embedded systems, rather than typical multi-user systems, data might be left over from previous processes. Quite likely, the previous use of the space was for something other than a pointer, so the value in it does not make sense when interpreted as a pointer. Its value as a pointer might point somewhere but not be meaningful in any way.
However, you cannot rely on this. The C standard does not define the behavior when you use an uninitialized object with automatic storage duration. In many C implementations, an uninitialized pointer will simply contain left over data. But, in some C implementations, the system may detect that you are using an uninitialized object and cause your program to crash. (Other behaviors are possible too.)

Why are the contents pointed to by a pointer not changed when memory is deallocated using free()?

I am a newbie when it comes to dynamic memory allocation. When we free the memory using void free(void *ptr) the memory is deallocated but the contents of the pointer are not deleted. Why is that? Is there any difference in more recent C compilers?
Computers don't "delete" memory as such, they just stop using all references to that memory cell and forget that anything of value is stored there. For example:
int* func (void)
{
int x = 5;
return &x;
}
printf("%d", *func()); // undefined behavior
Once the function has finished, the program stops reserving the memory location where x is stored, any other part of the program (or perhaps another program) is free to use it. So the above code could print 5, or it could print garbage, or it could even crash the program: referencing the contents of a memory cell that has ceased to be valid is undefined behavior.
Dynamic memory is no exception to this and works in the same manner. Once you have called free(), the contents of that part of the memory can be used by anyone.
Also, see this question.
The thing is that accessing memory after it has been freed is undefined behavior. It's not only that the memory contents are undefined, accessing them could lead to anything. At least some compilers when you build a debug version of the code, actually do change the contents of the memory to aid in debugging, but in release versions it's generally unnecessary to do that, so the memory is just left as is, but anyway, that is not something you can safely rely upon, don't access freed memory, it's unsafe!
In C, parameters are passed by value. So free just can't change the value of ptr.
Any change it would make would only change the value within the free function, and won't affect the caller's variable.
Also, changing it won't be so much help. There can be multiple pointers pointing to the same piece of memory, and they should all be reset when freeing. The language can't keep track of them all, so it leaves the programmer to handle the pointers.
This is very normal, because clearing the memory location after free is an overhead and generally not necessary. If you have security concerns, you can wrap the free call within a function which clears the region before freeing. You'll also notice that this requires the knowledge of the allocation size, which is another overhead.
Actually the C programming language specifies that after the lifetime of the object, even the value of any pointer pointing to it becomes indeterminate, i.e. you can't even depend on the pointer to even retain the original value.
That is because a good compiler will try to aggressively store all the variables into the CPU registers instead of memory. So after it sees that the program flow calls a function named free with the argument ptr, it can mark the register of the ptr free for other use, until it has been assigned to again, for example ptr = malloc(42);.
In between these two it could be seen changing the value, or comparing inequal against its original value, or other similar behaviour. Here's an example of what might happen.

malloc and scope

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!

Resources