Introduction to C Programming

Introduction to C Programming by Rob Miles, Electronic Engineering


Memory

Fetching Memory
malloc
free
The heap

Fetching Memory

Sometimes you will come across situations where you do not know when the program runs exactly how much memory your program will need, for example you may want the user to tell you how many items he or she wants to store, and then get a chunk of memory just the right size. This is the most efficient way of writing your programs, it means that you do not use more resources than required. When a C program runs, a number of services are made available to it by the system it is running on. One of these is a memory manager. The memory manager looks after what memory is used by who. On a single user system, like the IBM PC, this is a very simple affair, either you have the memory or the system does. On a multi-user system, like UNIX, things are a lot more complicated. You however do not need to worry about this, you simply ask the memory manager for a chunk of memory and it will give you it if there is enough left. When you have finished with the memory it is nice if you give it back, so that other programs can use it.

The include file alloc.h contains all the memory allocation routines. You can find out how much memory is left, the size of the biggest block available and things like that. We are only going to use two, malloc and free.

malloc

This function will try to get a chunk of memory for you. It returns a pointer to the memory it found, if it could get some. If not it returns a NULL pointer. You must always check to make sure that malloc worked before you use the memory you think you got! malloc has one parameter, the size of the block of memory you want. You can use sizeof to find out how much memory you need, for example :

sizeof ( int ) * 99

- would be enough space for 99 integers. Because malloc returns a pointer to an item of type void you must use the cast facility to make this compatible with the type you really want; i.e. if you want to store 99 integers you will have a pointer to integers which you want to make point at the block of memory which malloc is going to get for you. The cast will make sure that the compiler does not produce an error when it sees the assignment, for example :

int * buffer ;
buffer = (int *) malloc ( sizeof ( int ) * 99 ) ;
if ( buffer == NULL ) {
	printf ( "No memory!\n" ) ;
}
else	{
	......
	do something with the memory...
	......
}

I would access an item in buffer in exactly the same way as I would access elements in any block of memory or array, for example buffer [20]. Note that the effects of going over the end of a block of memory which has been fetched in this way as just the same as any other - your program will do stupid things and then fall over! Note also that you have no idea what is in the memory when you get it! Do not assume that it has been emptied of silly values. There is a function, calloc, which you can use if you want all your memory to be cleared before you get it. This function is used differently from malloc, so you will have to look it up.

free

When you have finished with some memory you can give it back to the memory manager by the use of the free function, for example :

free ( buffer ) ;

This would give back the memory we requested above. Note that if we try to use this memory again, it may have been used for something else and so this would cause big problems. It is good housekeeping to always give back memory which you have allocated. If you do not you might find that the total amount of memory available will drop to a point where your program will not run any more.


The heap

The area of memory which is used for malloc and free is often called the heap. The name is apt, there is no organisation of it so after a while it becomes a mess. This can be a problem; what usually happens is that the heap becomes fragmented. This means that there is a lot of free space, but it is spread all over the heap. Your program can then fail to get the memory it wants, not because there is insufficient available, but because there is not a single chunk of the required size. You can guard against this happening by not allocating and freeing lots of little bits of memory repeatedly. Try to work by just grabbing a chunk and then holding on to it. Do not worry about giving it back if you know you will need it later.

If you want to be totally selfish, but also bomb proof, grab a very large amount of memory at the start and then manage it yourself. The advantage of doing it this way is that you can be sure when your program starts that it will have enough memory to run right to the end.


Rob Miles, R.S.Miles@e-eng.hull.ac.uk, Electronic Engineering
HTML by Bronwen Reid, July 1995