I am working in large application which is written in C. We allocate memory through malloc and release the memory free for different pointer. I have seen all time we have repeat check
for memory failure case than release the memory.
I am planning to write a utility in which the programmer will pass the pointer which they want to
create and we will take care all of allocation and release of memory.
Does anyone have idea any utility function which can be use in C for allocation and release memory.
The first answer came my mind was boost library but I have received answer from my organization that they do not want to use boost library.
How about Boehm Garbage Collector?
If you are just looking for a unified way (without code duplication) to check if allocation was successful or not, please see the last segment of this post.
First of all boost is mainly a library for C++, therefor all of boost can't be used in C.
Writing your own Garbage Collector is not easy, especially in a language without true OOP (such as C). There are many implementations of garbage collectors available online, so instead of reinventing the wheel you could check out some of them.
If you are not going to use any of them, well.. at least they will provide you with some information regarding how the problem can be solved.
A garbage collector for C and C++ (Boehm-Demers-Weiser) [recommended]
Using the C/C++ Garbage Collection Library, libgc
Depending on the project size you might be better of using valgrind looking for leaking data and then manage the memory allocation/release by yourself.
C has been around for many years, and a lot of developers have managed without a automatic garbage collector. Why shouldn't you be able to do the same?
Simple error checking on allocation (and abort on error)
#include <stdio.h>
#include <stdlib.h>
void*
safe_alloc_check (void *p, size_t size) {
if (p == NULL) {
printf ("ERROR: Unable to allocate memory for %lu bytes!", size);
exit (-1);
}
return p;
}
#define s_malloc(N) safe_alloc_check(malloc(N),N)
#define s_calloc(C,N) safe_alloc_check(calloc(C,N),N)
#define s_realloc(P,N) safe_alloc_check(realloc(P,N),N)
...
int *p = s_malloc (sizeof (int));
Wrap malloc in a function (often called xmalloc) which aborts when malloc fails to return a new memory chunk (by returning NULL).
If you are on a Unix system, using valgrind to catch memory leaks is helpful.
If you want a garbage collector for C, consider using Boehm's garbage collector
I'm not sure what you're after. An often used technique for handling memory allocation and deallocation in C is implementing a memory trace data structure which holds a number of pointers to memory that has been allocated using your own implementation of malloc, calloc, realloc, e.g. mymalloc, mycalloc, myrealloc (calling the original functions themselves) and then using a new function free_memtrace to free all the memory that has been recorded in a trace in one function call.
So e.g. you could do
MEMTRACE mt; // Possibly a module-scoped global variable
begin_memtrace( &mt );
ptr1 = mymalloc( size );
ptr2 = mycalloc( n, sizeof(type) );
end_memtrace( &mt );
and then at some point in your program
free_memtrace( &mt );
to clear the memory recorded in mt.
The begin_memtrace, end_memtrace functions are needed so that your allocation functions "know" where to record the pointers. That information could be stored locally in the module where you implement mymalloc, mycalloc, myfree, free_memtrace ....
Related
As an assignment in operating systems we have to write our own code for malloc and free in C programming language, I know if i asked the code for it there is no point of me to study. i'm facing the problem of not knowing where to include initializing char array with 50000 bytes and making two lists free and used. in my function i can't trigger malloc or free to happen automatically. and a 3rd party main program will be used to test my functions.....
if my file is mymalloc.c or what ever
void* myalloc(size_t size)
{
//code for allocating memory
}
void myfree(void *ptr)
{
//code for free the memory
}
where do the code for initiating memory space and lists will go..
I will provide you with the basic concept which you can use to write your own code for malloc() and free() functions using C.
Assume that we have a contiguous block of memory of a certain size. It will be our abstract sense of memory which will carry all the requested memory allocations plus the data structures that are used to hold data about those allocated blocks.
We use a simple linked list to carry the data related to the allocated as well as free blocks of memory.
Its structure is as follows.
struct block{
size_t size; /*Specifies the size of the block to which it refers*/
int free; /*This is the flag used to identify whether a block is free
or not*/
struct block *next; /*This points to the next metadata block*/
};
You will need 2 source files for this purpose. One is mymalloc.h which is the header file which contains the initialization parts and the function prototypes of the rest of the functions that we are going to implement. The other is the mymalloc.c source file which contains all the necessary function implementations.
There needs to be a function to initialize the first free memory block.
And another function to split a block of memory which has more than enough space to give to the requested size. And another method to scan through the linked list and merge any consecutive blocks that are free, so that it prevents external fragmentation.
Note: We use the First-fit-algorithm to find a free block to allocate memory.
I think this will help anyone who is in search of a simple way to write their own malloc and free functions using C. Please follow the following link for a detailed explanation.
http://tharikasblogs.blogspot.com/p/how-to-write-your-own-malloc-and-free.html
I think you only have to implement a memory manager. So you don't have to use brk, sbrk, ...
Just put used memory in a simple array and fragment it somehow. Since it's homework you want to make it as simple as possible or else you run into problems due to complexity/time constraints of your assignment.
You only have to decide which tactic you want to use. I'd suggest to use the buddy system. Though it's a bit more complicated than the most simple ones.. maybe fixed sized fragmentation is simpler..
Maybe this is also a good read.
Don't do something low-level as suggested in the other answers..
The implementation greatly depends upon operating system and architecture, anyhow you may take a look at this: http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html
(and study how it works!).
If you are on a unix system you can look the manual of brk and sbrk. Those system calls "push/set" the limit of the heap.
Using those you can manage your memory pages, allocating them as you need.
I would advise a chained-list to manage your different allocated spaces and building functions to split them or to merge them if they are free.
If you need to try your code with high-level applications, you can name your functions malloc/free, compile them to a shared-object (.so) and then use LD_PRELOAD and LD_LIBRARY_PATH environment variables to load your .so and replace system's malloc.
Every command you call then will use your shared object and thus your malloc, telling you if your malloc is stable or if it fails to comply with reality.
If you need a clear example of this i'd be happy to put some code here, but I do not want to make my answer too hard to read.
First, you could make a fake malloc which always fail
/* fake malloc */
void* myalloc(size_t sz)
{ return NULL; }
but that is "cheating". You want to make a malloc which is useful.
You probably want to make a system call which asks the kernel for memory. Of course, you'll need the symetrical syscall to release memory. On Linux and many Posix systems you'll often use mmap and munmap syscalls.
(You could also use sbrk, but using mmap with munmap is easier and more general)
The idea is that you get big chunks of memory (with mmap) and then you manage smaller memory zones inside. The interesting detail is how to manage these smaller zones. You may want to deal with large malloc differently than "small" allocations.
You really want to read wikipedia page on memory allocation
You could have a global static variable that is initialized to zero. Then check that variable at the start of your malloc and free function. In your malloc function, if the variable is zero then initialize whatever you need, and then set the variable to non-zero. In your free function, just return if the variable is zero.
More like that, is a simple malloc :
void* my_malloc(size_t size)
{
return (sbrk(size));
}
man sbrk will help you.
The problem now is to create a free and to create a efficient malloc :-)
if you want to test your malloc you can do like this :
$> LD_PRELOAD=/mypath/my_malloc.so /bin/ls
but you need to create a dynamic library before because malloc is a .so
If we would like to check for memory leaks in a C++ program, we can overload the new and delete operators to keep track of the memory that was allocated. What if we would like to check for leaks in a C program? Since there is no operator overloading in C, can we over-write the malloc function pointer to intercept calls to malloc and track memory allocation? Is there an easier way without using any external utilities? Please provide some code as I am not familiar with over-writing method pointers.
Note: I would like to do this without any external utilities for practice.
As suggested, there already exist excellent tools like Valgrind to do this.
Further:
I would like to do this without any external utilities for practice
This is interesting and I am sure would be fulfilling,
You can use macro trick to detect such memory usage and leak errors, in fact write your own neat leak detector. You should be able to do this as long as you have a single allocation and deallocation function in your project.
#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)
void* my_malloc(size_t size, const char *file, int line, const char *func)
{
void *p = malloc(size);
printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);
/*Link List functionality goes in here*/
return p;
}
You maintain a Linked List of addresses being allocated with the file and line number from where there allocated. You update the link list with entries in your malloc.
Similar to above you can write an implementation for free, wherein you check the address entries being asked to be freed against your linked list. If there is no matching entry its a usage error and you can flag it so.
At the end of your program you print or write the contents of your linked list to an logfile. If there are no leaks your linked list should have no entries but if there are some leaks then the logfile gives you exact location of where the memory was allocated.
Note that in using this macro trick, you lose the type checking which functions offer but it's a neat little trick I use a lot of times.
Hope this helps and All the Best :)
Valgrind is what you need.
I remember reading first chapter of Algorithms in a Nutshell which talked about this although it didn't include code. Just added in case you find it interesting.
since there is no operator overloading in c can we over-write malloc
function point to intercept calls to malloc and track memory
allocation
Actually, you can. GIve LD_PRELOAD a read.
In addition to #Als's answer which will wrap calls in your source code, if you're using gnu ld, you can have the linker wrap all calls (presumably to malloc, realloc, calloc, and free) at link time, irrespective of where they come from. You then write __wrap_malloc etc and can call the original function with, for example, __real_malloc.
See --wrap=symbol in http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html
I don't know how this works with calls from shared libraries. I'm guessing it doesn't.
Use mallinfo function it worked for me on Xilinx Zynq baremetal using Xilinx SDK gcc. I tested with intentional memory leak - I have no idea why but google results are were incredibly terrible at finding this solution spread the word to help other devs!
# include <stdio.h>
# include <stdbool.h>
# include <string.h>
# include <stdlib.h>
int main ()
{
char * buffer;
buffer = malloc (2);
if (buffer == NULL){
printf("big errors");
}
strcpy(buffer, "hello");
printf("buffer is %s\n", buffer);
free(buffer);
return 0;
}
I allocated 2 bytes of memory to the pointer/char buffer yet if I assign the C-style string hello to it, it still prints the entire string, without giving me any errors. Why doesn't the compiler give me an error telling me there isn't enough memory allocated? I read a couple of questions that ask how to check how much memory malloc actually allocates but I didn't find a concrete answer. Shouldn't the free function have to know exactly how much memory is allocated to buffer?
The compiler doesn't know. This is the joy and terror of C. malloc belongs to the runtime. All the compilers knows is that you have told it that it returns a void*, it has no idea how much, or how much strcpy is going to copy.
Tools like valgrind detect some of these errors. Other programming languages make it harder to shoot yourself in the foot. Not C.
No production malloc() implementation should prevent you from trying to write past what you allocated. It is assumed that if you allocate 123 bytes, you will use all or less than what you allocated. malloc(), for efficiency sake, has to assume that a programmer is going to keep track of their pointers.
Using memory that you didn't explicitly and successfully ask malloc() to give you is undefined behavior. You might have asked for n bytes but got n + x, due to the malloc() implementation optimizing for byte alignment. Or you could be writing to a black hole. You never can know, that's why it's undefined behavior.
That being said ...
There are malloc() implementations that give you built in statistics and debugging, however these need to be used in lieu of the standard malloc() facility just like you would if you were using a garbage collected variety.
I've also seen variants designed strictly for LD_PRELOAD that expose a function to allow you to define a callback with at least one void pointer as an argument. That argument expects a structure that contains the statistical data. Other tools like electric fence will simply halt your program on the exact instruction that resulted in an overrun or access to invalid blocks. As #R.. points out in comments, that is great for debugging but horribly inefficient.
In all honesty or (as they say) 'at the end of the day' - it's much easier to use a heap profiler such as Valgrind and its associated tools (massif) in this case which will give you quite a bit of information. In this particular case, Valgrind would have pointed out the obvious - you wrote past the allocated boundary. In most cases, however when this is not intentional, a good profiler / error detector is priceless.
Using a profiler isn't always possible due to:
Timing issues while running under a profiler (but those are common any time calls to malloc() are intercepted).
Profiler is not available for your platform / arch
The debug data (from a logging malloc()) must be an integral part of the program
We used a variant of the library that I linked in HelenOS (I'm not sure if they're still using it) for quite a while, as debugging at the VMM was known to cause insanity.
Still, think hard about future ramifications when considering a drop in replacement, when it comes to the malloc() facility you almost always want to use what the system ships.
How much malloc internally allocates is implementation-dependent and OS-dependent (e.g. multiples of 8 bytes or more). Your writing into the un-allocated bytes may lead to overwriting other variable's values even if your compiler and run-time dont detect the error. The free-function remembers the number of bytes allocated separate from the allocated region, for example in a free-list.
Why doesnt the compiler give me an
error telling me there isnt enough
memory allocated ?
C does not block you from using memory you should not. You can use that memory, but it is bad and result in Undefined Behaviour. You are writing in a place you should not. This program might appear as running correctly, but might later crash. This is UB. you do not know what might happen.
This is what is happening with your strcpy(). You write in place you do not own, but the language does not protect you from that. So you should make sure you always know what and where you are writing, or make sure you stop when you are about to exceed valid memory bounds.
I read a couple of questions that ask
how to check how much memory malloc
actually allocates but I didn't find a
concrete answer. Shouldn't the 'free'
function have to know how much memory
is exactly allocated to 'buffer' ?
malloc() might allocate more memory than you request cause of bit padding.
More : http://en.wikipedia.org/wiki/Data_structure_alignment
free() free-s the exact same amount you allocated with malloc(), but it is not as smart as you think. Eg:
int main()
{
char * ptr = malloc(10);
if(ptr)
{
++ptr; // Now on ptr+1
free(ptr); // Undefined Behaviour
}
}
You should always free() a pointer which points to the first block. Doing a free(0) is safe.
You've written past the end of the buffer you allocated. The result is undefined behavior. Some run time libraries with the right options have at least some ability to diagnose problems like this, but not all do, and even those that do only do so at run-time, and usually only when compiled with the correct options.
Malloc -> how much memory has been allocated?
When you allocate memory using malloc. On success it allocates memory and default allocation is 128k. first call to malloc gives you 128k.
what you requested is buffer = malloc (2); Though you requested 2 bytes. It has allocated 128k.
strcpy(buffer, "hello"); Allocated 128k chunk it started processing your request. "Hello"
string can fit into this.
This pgm will make you clear.
int main()
{
int *p= (int *) malloc(2);---> request is only 2bytes
p[0]=100;
p[1]=200;
p[2]=300;
p[3]=400;
p[4]=500;
int i=0;
for(;i<5;i++,p++)enter code here
printf("%d\t",*p);
}
On first call to malloc. It allocates 128k---> from that it process your request (2 bytes). The string "hello" can fit into it. Again when second call to malloc it process your request from 128k.
Beyond 128k it uses mmap interface. You can refer to man page of malloc.
There is no compiler/platform independent way of finding out how much memory malloc actually allocated. malloc will in general allocation slightly more than you ask it for see here:
http://41j.com/blog/2011/09/finding-out-how-much-memory-was-allocated/
On Linux you can use malloc_usable_size to find out how much memory you can use. On MacOS and other BSD platforms you can use malloc_size. The post linked above has complete examples of both these techniques.
Is there a one-liner that will free the memory that is being taken by all pointers you created using mallocs? Or can this only be done manually by freeing every pointer separately?
you could do that by creating some kind of "wrapper" around malloc.
(warning that's only pseudo code showing the idea, there is no checking at all)
void* your_malloc(size_t size)
{
void* ptr = malloc(size);
// add ptr to a list of allocated ptrs here
return ptr;
}
void your_free(void *pointer)
{
for each pointer in your list
{
free( ptr_in_your_list );
}
}
But it doesn't sound like a good idea and I would certainly not do that, at least for general purpose allocation / deallocation. You'd better allocate and free memory responsibly when it is no longer needed.
You might want to look into memory pools. These are data structures built to do exactly this.
One common implementation is in the Apache Portable Runtime, which is used in the Apache web server, as well as other projects, such as Subversion.
malloc on it's own has implementation-defined behavior. So there isn't a necessity for it to keep track of all the pointers it has, which obviously puts a damper on the idea.
You'd need to make your own memory manager that tracks the pointers, and then provides a function called free_all or something that goes through the list of pointers it has and calls free on them.
Note, this sounds like a somewhat bad idea. It's better to be a bit more strict/responsible about your memory usage, and free things when you're done; not leave them hanging about.
Perhaps with a bit more background on where you want to apply your idea, we might find easier solutions.
Check out dlmalloc
ftp://g.oswego.edu/pub/misc/malloc.h
look at the following functions
/*
mspace is an opaque type representing an independent
region of space that supports mspace_malloc, etc.
*/
typedef void* mspace;
/*
create_mspace creates and returns a new independent space with the
given initial capacity, or, if 0, the default granularity size. It
returns null if there is no system memory available to create the
space. If argument locked is non-zero, the space uses a separate
lock to control access. The capacity of the space will grow
dynamically as needed to service mspace_malloc requests. You can
control the sizes of incremental increases of this space by
compiling with a different DEFAULT_GRANULARITY or dynamically
setting with mallopt(M_GRANULARITY, value).
*/
mspace create_mspace(size_t capacity, int locked);
/*
destroy_mspace destroys the given space, and attempts to return all
of its memory back to the system, returning the total number of
bytes freed. After destruction, the results of access to all memory
used by the space become undefined.
*/
size_t destroy_mspace(mspace msp);
...
/*
The following operate identically to their malloc counterparts
but operate only for the given mspace argument
*/
void* mspace_malloc(mspace msp, size_t bytes);
void mspace_free(mspace msp, void* mem);
void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
void* mspace_realloc(mspace msp, void* mem, size_t newsize);
You might want to do something called "arena allocation", where you allocate certain requests from a common "arena" which can be freed all at once when you're done.
If you're on Windows, you can use HeapCreate to create an arena, HeapAlloc to get memory from the heap/arena you just created, and HeapDestroy to free it all at once.
Note that when your program exit()s, all the memory you allocated with malloc() is freed.
Yes, you can do that unless you write your own defintion of malloc() and free(). You should probably call myCustomMalloc() instead of regular malloc() and you should be keeping track of all the pointers in some memory location and when you call the myCustomFree() method, you should be able to clear all the pointers that was created using your myCustomMalloc(). Note: both your custom methods will be calling malloc() and free() internally
By this way you can achieve your goal. I am a java person but I use to work a lot in C in my early days. I assume that you're trying to achieve a common solution where memory is being handled by the compiler. That has a cost of performance as it is seen in Java. You dont have to worry about allocation and freeing the memory. But that has a severe effect on performance. Its a tradeoff that you have to live with.
I was told by a rather smart person that you cannot implement garbage collection in C because of it's weakly typed. The basic idea seems to be that C gives you too much freedom. He mentioned casting pointers without type checking...
I don't really grok the idea. Can someone give me an explanation and possibly a code sample of why this wouldn't work.
NOTE: Obviously C is about speed and why would you want to add garbage collection? I'm just curious really.
He probably referred to the fact that you can cast a pointer to an int and back to the original pointer type. It's pretty much impossible for a GC to clean up correctly when you do that, consider:
char * p = (char *) malloc(16);
int i = (int) p;
p = 0;
// GC runs and finds that the memory is no longer referenced
p = (char *) i;
// p is now a dangling pointer
EDIT: The above will only produce a dangling pointer with a precise GC. As others have pointed out, a conservative collector can still correctly handle this scenario as it assumes that any bit pattern that could be a valid pointer actually is a pointer and will thus not free the memory allocated. However, this is of course no longer possible when i is further modified such that it no longer looks like a valid pointer to the collector, e.g. as follows:
char * p = (char *) malloc(16);
int i = ~((int) p);
p = 0;
// GC runs and finds that the memory is no longer referenced
p = (char *) ~i;
// p is now a dangling pointer
Moreover, (again as others have pointed out) it's only impossible to implement a GC for C if you want to retain the full functionality of the language. If you refrain from using tricks like the above (i.e. you confine yourself to a subset of the possible operations) then GC is indeed feasible.
It's perfectly possible to implement whatever memory manager you can think of in C. The catch is that you then have to use its allocation/deallocation functions exclusively and restrict your 'pointer magic' to things it can keep track of. Aditionally, the memory management might be restricted to certain supported types.
For example, Objective-C's retain/release system and autorelease pools are basically memory managers implemented in C. Many libraries also implement their own, simple form of memory management like reference counting.
Then, there's the Boehm garbage collector. To use it, just replace your malloc()/realloc() calls with the Boehm versions and you never have to call free() again. Read about the possible issues with this approach.
Also, check this wikipedia page for a quick overview on how conservative garbage collectors work.
If you read the right papers and you have a bachelor's degree in CS, it's actually pretty easy to implement a decent conservative garbage collector for C---I have a dozen students who have done it as a class exercise taking about four weeks. Then spend 20 years improving it and you get the Boehm collector (libgc).
The basic idea is simple: if there is a bit pattern anywhere in a register, on the stack, in a global variable, or in a live heap object, and that bit pattern happens to be an address that falls inside an object allocated with malloc, than that object is considered live. Any object that is not live cannot possibly be reached by following pointers, and so it can be reclaimed and used to satisfy future allocation requests. This technique operates on the hardware representation of pointers, and it is completely independent of the type of pointer---types are irrelevant here.
It is true there is a caveat: conservative garbage-collection techniques can be fooled by willfully hiding pointers. Compress pointer-containing structures, keep the only copy of a pointer on disk, obfuscate a pointer by XORing 0xdeadbeef, and all these techniques will break a conservative collector. But this kind of problem is extremely rare unless done deliberately. Authors of optimizing compilers are usually careful not to hide pointers from such a collector.
The most interesting part of your question is why do it. Three reasons:
It eliminates the possibility of many memory-manangement bugs.
It simplifies your APIs because it is no longer necessary to specify who allocates memory, who owns the allocated memory, whether it's necessary to copy memory, and who is responsible for freeing memory.
Believe it or not, it can be faster than using malloc and free.
It's not impossible to implement a garbage collector for C (and in fact, they do exist, as a simple google search reveals), it's just difficult, because it can be difficult to determine if a certain string of bits is a pointer into an allocated block or just looks like one.
The reason this is an issue is because C (and C++, for that matter) allows you to cast from a pointer type to an integral type, so an integer variable might hold an address within an allocated block, preventing the GC from freeing that block, even though that value wasn't intended to be a pointer.
For example, let's say I have a block of memory allocated. Let's suppose this block of memory is allocated starting at address 0x00100000 (1,048,576), and is 1 MB long, so extends to 0x001FFFFF (2,097,151).
Let's say I also am storing the size of an image file in a variable (let's call it fileSize). This image file happens to be 1.5 MB (1,572,864 bytes).
So when the garbage collector runs, it will come across my fileSize variable, find it containing a value that corresponds to an address within my allocated block, and decide that it cannot free this block, lest it invalidate my maybe pointer. That's because the GC doesn't know if I've done this:
int fileSize;
{
char *mem = (char*)malloc(1048576);
fileSize = (int)(mem + 524288);
}
// say GC runs here
or if I've just done this:
int fileSize;
{
char *mem = (char*)malloc(1048576);
fileSize = 1572864;
}
// say GC runs here;
In the latter case, it is safe to free the block at *mem, (if no other references exist), whereas in the former, it's not. It must be conservative and assume that it's not, so the memory "leaks" (at least until fileSize goes out of scope or is changed to a value outside the allocated block).
But garbage collectors for C (and C++) do exist. Whether or not they are valuable is a matter for a different discussion.
The problem is that there's no way for the runtime to know for certain if any piece of memory is referenced or not. Even if you wrap all memory allocation in code that registers the usage, you can still obtain pointers to used memory via regular pointer manipulation (or by mistake). Casts only make the problem harder for the runtime. So if the runtime frees a piece of memory, it will mess things up for any pointers still pointing to that area of memory. Obviously the situation only gets worse when you consider that garbage collection has to work for multi-threaded applications as well.
It's impossible to implement a precise garbage collector for C because of the freedoms afforded C's pointers and the fact that the length of a C array is anyone's guess. This means a lot of sophisticated garbage collection approaches can't be used. (Copying and compacting garbage collectors come to mind.)
It is, however, possible to implement a conservative garbage collector (boehm), which basically assumes everything that looks like it might be a pointer is a pointer. This isn't very efficient, but it works for a suitably lenient definition of "works".
C is not weakly typed, but this code illustrates the difficulty in building a garbage collector into the language:
#include <stdio.h>
#include <stdlib.h>
int GetSomeMemory() {
char* pointerToHeapMemory = malloc(10);
return (int)pointerToHeapMemory;
}
int main() {
int memoryAddress = GetSomeMemory();
/* at this point a garbage collector might decide to clear up the memory that
* was allocated in GetSomeMemory on the grounds that pointerToHeapMemory
* is no longer in scope. But the truth is we still know about that memory and
* we're about to use it again... */
char* anotherPointerToHeapMemory = (char*) memoryAddress;
sprintf(anotherPointerToHeapMemory, "123456789\0");
printf("%s\n", anotherPointerToHeapMemory);
}
Garbage collection can be done so long as everyone working on a project agrees to avoid this kind of thing and use a common set of functions for allocating and accessing memory. For example, this is a C garbage collector implementation