technically the free(a)
should be after the loop. It likely will never make a difference, but that is dependent on your OS and stdlib implementations, whether or not free()
actually returns a page to the OS or simple keeps it in reserve.
Although I am slightly surprised that it does not crash...although I do suppose it would likely never crash on a 32-bit machine, or compiled for 32-bit, but the values returned by malloc [while valid unless NULL] are not decidable. while it is extremely unlikely they point to valid memory locations on a 64-bit system after everything has run, it is extremely unlikely.
@The_Space_Bear one thing you may not have noticed is that his typing is off. He declared a as a single pointer. "array"s don't truly exist in C, the syntax is just shorthand pointer arithmetic and dereferencing. Though he assigned enough memory for it to function, since a is declared as pointing to an integer and not another pointer, the pointer arithmetic would [typically] only increment 4 bytes when a pointer would require 8 byte offsets on a 64-bit system.
Often times malloc
does it's own bookkeeping in memory adjacent to one or both sides of the returned value.
What would be correct is (note the type of a
):
`
int i;
int *a = malloc(3sizeof(int*)); // doesnt point to an int, points to a pointer.
for(i = 0; i < 3; i++)
{
a[i] = malloc(sizeof(int)); // a[i] points directly to an int.
a[i][0] = i;
}
for(i = 0; i < 3; i++)
{
free(a[i]);
}
free(a);
`
Now, if the question is about free
, every malloc
must have a corresponding call to free
. If it does not, that is what is called a memory leak.
malloc
dynamically allocates memory in a big, open, unstructured area of program memory called the heap. malloc
itself does internal bookkeeping to keep track of what has NOT been allocated in the heap. This is typically a doubly linked list of memory blocks. When it allocates something, it also puts a tag on it (usually in the 8 bytes in front of the returned pointer) detailing what it did. free
uses this tag to add the memory back to malloc
's list.
I do not know if you are familiar with the halting problem, or undecidability in general, but malloc
has no way to know what you are actually doing with the memory. So unless you explicitly call free
, you are 'using' the memory, even if your program no longer has any references to it. Again, being undecidable, once you loose the reference, you can never know again where it pointed to use or to free
, therefore malloc
will consider it forever (being until your program exits) in use. Similarly, the OS has no way to know what you're doing with the memory it gives you. It only knows your program no longer needs memory after it exits.
So, ultimately free
is declaring you are finished with a block of memory you got form malloc
. free(a)
should have been called after the second loop, because free
means you are done. if you are done, you cannot truly guarantee what value will be in that memory anymore. malloc
may have returned that value somewhere else for re-use, since you said you were done. In a program of this scope, it might seem like a non-issue, but this is the sort of non-issue that can easily slip in and break any reasonably complex program. A lot of people got mad at MS after moving from DOS to Windows when Sim City had a similar bug. DOS didn't enforce memory bounds, so any program could write over any other program's memory. Windows did enforce them, and Sim City [correctly] broke when it accessed some memory after freeing it.