//// Restrictions

// Only the following libraries can be included in this file:

// #include <string>   // Strings
// #include <iostream> // C++ style I/O
// #include <cstdio>   // If you prefer C style I/O

// These libraries are optional (as your allocator is not required to produce
// output) but printing information about what your allocator is doing can
// be useful for debugging.

// All debugging output should either be printed to standard error (std::cerr)
// or removed from your program before submitting to Marmoset.

// Preprocessor macros (#define) are not allowed as they may interfere with
// the test programs used by Marmoset.

//// Function definitions begin

// Initialization logic for the allocator goes here.
//
// The main program will call this once, before any calls to New or Delete.
// It will pass in a pointer 'heapStart' to a block of memory large enough
// to store 'heapSize' int values.
//
// This block of memory should be used for all heap allocations.
// You should save the 'heapStart' pointer in a global variable so that New
// and Delete and any helper functions you write can refer to it.
//
// Also do any other necessary setup here, e.g., initializing your free list.
void Init(int *heapStart, int heapSize) { }

// Allocates a block of n ints.
// Returns an integer offset i such that (heapStart + i) is the address of
// the block. If the address of the block is 'addr', this offset can be
// computed by doing the pointer-pointer subtraction (addr - heapStart).
//
// If allocation is not possible because a large enough block of memory is
// not available, return a negative integer.
//
// Note that the offset returned to the user should be PAST any bookkeeping
// information used by the allocator. For example, if you use the first word
// of the block to store size information, you should return the offset of
// the second word. This ensures the user does not modify the allocator's
// internal bookkeeping information.
int New(int n) { return -241; }

// Deallocates the block at the given memory address.
// If the memory address is a null pointer, this function should do nothing.
// Otherwise, make the block available for future allocations with New.
//
// You may assume this function will only ever be called with a null pointer
// or the address of a currently allocated block. (Trying to free an already
// freed block is a user error and it is not the responsibility of the
// memory allocator to deal with this.)
//
// If you are using the free list algorithm, it is important that this
// function merges adjacent free blocks, or you will waste lots of memory.
void Delete(int *addr) { }
