(This document was last modified on Saturday, February 11, 2017 at 11:18:49 PM.)
This assignment is intended as a “warm-up” assigment
to review C programming,
and to get you familiar with using UNIX, etc.,
It also gives you some idea of memory management at the user level.
It is also designed to give you an idea of whether or not you
have the background to take this course.
The goal is to implement a simple version of
its associated functions,
This function allocates a block of memory of size bytes. If size is zero, it returnsvoid *malloc(size_t size);
NULL. The returned address must be aligned to a multiple of 8. Also, the memory returned from calloc() and realloc() must be aligned to 8.
This function frees a block of memory that had previously been allocated. If ptr isvoid free(void *ptr);
NULL, this function does nothing.
This function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory. The memory is set to zero. If nmemb or size is 0, then this returnsvoid *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
realloc()changes the size of the memory block pointed to by ptr to size bytes. Existing contents will not be changed, however, a new memory block with a copy of the original contents may be returned. In any case, the contents will be unchanged to the minimum of the old and new sizes; and any newly allocated memory will be uninitialized.
If ptr is
then the call is equivalent to just calling
for all values of size;
if size is equal to zero,
and ptr is not
then the call is equivalent to
Unless ptr is
it must have been returned by an earlier call to
If a new block had to be allocated
to accommodate the new size,
the old block should be freed.
To obtain memory from the OS,
sbrk() system call.
This call increases the size of the heap by the given amount,
and returns the previous limit.
man page for details.
free() is called,
the memory cannot usually be returned to the OS,
due to contiguity restrictions.
So your implementation should simply put this
memory on its own internal free set.
malloc() is called,
your implementation should first check
your internal free set.
Only if the memory is not available there
should your implementation call
sbrk() to request another chunk.
To keep things relatively simple,
all block sizes should be based on powers of 2.
You should use a best fit strategy to allocate from your free set.
In other words, return the smallest block that will satisfy the
If the block is larger than needed,
you must split the block if there is enough free space to create a block of the next smaller power of 2.
However, you are also allowed to maintain a reasonable minimum size of a block.
In other words, if the unused space available is smaller than a reasonable limit, you
do not need to split the block.
Also, you must merge adjacent free blocks. In other words, if two free blocks are adjacent, they must be merged into a single, contiguous free block. Your merge code does not need to be efficient.
To help you get started,
an example is here that uses
Note that there may be library functions that you cannot call,
because some library functions may internally call
leading to problems such as an infinite recursion.
A test program is here.
Do not use any floating point functions that require linking with