For a project I had to do a memory management problem without creating any custom classes or templates using the provided pool
array and poolSize
.
I implemented all functions and created two extra, SizeConversion
and GetSize
. My main question is this: is there a better way to implement this and is the code that I have clean and efficient?
const int poolSize = 65536;
char pool[poolSize];
int SizeConversion(int);
int GetSize(int, int);
// Initialize set up any data needed to manage the memory pool
void initializeMemoryManager(void)
{
//Verify that the pool is preset to null
for (int x = 0; x < poolSize; x++) {
pool[x] = '\0';
}
}
// return a pointer inside the memory pool
// If no chunk can accommodate aSize call onOutOfMemory()
void* allocate(int aSize)
{
//Check if the allocation size requires more than 2 bytes to determine length
if (aSize >= (256 * 256)) {
onIllegalOperation("Allocation Size too Large");
return nullptr;
}
else {
int first = 0;
int cur = 0;
//Find the first location the data can be stored
for (int x = 0; x < poolSize; x++) {
//Save first location if not set, otherwise increment cur
if (pool[x] == '\0') {
if (cur == 0)
first = x;
cur++;
}
else {
cur = 0;
//Get the integer value of the two size bytes
int sr = (int)pool[x];
int sl = (int)pool[x + 1];
//Jump from current index to end of allocation then continue
x = x + 1 + GetSize(sl, sr);
}
//If cur is larger than the necessary size, use
if (cur >= aSize + 2) {
break;
}
}
//Define the allocated data for display purposes to 'A'
for (int x = first + 2; x < first + 2 + aSize; x++) {
pool[x] = 'A';
}
//Define the size of the data from range of 1-255
pool[first] = (char)((int)((aSize+1) / 256) + 1);
pool[first + 1] = (char)((aSize - ((int)pool[first] - 1) * 256) + 1);
//Return a pointer to the first value index of allocation
return ((void*)(pool + first + 2));
}
}
//Since characters are signed, if they are below zero then continue normal ordering
int SizeConversion(int x) {
if (x < 0) {
x = 256 + x;
}
return x;
}
//Get the total size of a single allocation
int GetSize(int right, int left) {
//Convert characters to correct integer values
right = SizeConversion(right);
left = SizeConversion(left);
//Get the total allocation size of entry
int r = (right - 1) + (left - 1) * 256;
return r;
}
// Free up a chunk previously allocated
void deallocate(void* aPointer)
{
if (aPointer == nullptr)
onIllegalOperation("Cannot Deallocate Pointer Without Address");
else {
//Convert Characters to integers for sizing
int x1 = (int)(*((char*)aPointer - 1));
int x2 = ((int)(*((char*)aPointer - 2)));
//Get the total allocation size of entry
int x = GetSize(x1, x2);
int i = 0;
//Deallocate values
while (x > i) {
*((char*)aPointer + i) = '\0';
i++;
}
//Deallocated Allocation size parameters
*((char*)aPointer - 1) = '\0';
*((char*)aPointer - 2) = '\0';
}
}
// Will scan the memory pool and return the total free space remaining
int freeRemaining(void)
{
int remaining = 0;
for (int x = 0; x < poolSize; x++) {
//Increase remaining if location is null
if (pool[x] == '\0') {
remaining++;
}
else {
//Get the integer value of the two size bytes
int sr = (int)pool[x];
int sl = (int)pool[x + 1];
//Jump from current index to end of allocation then continue
x = x + 1 + GetSize(sl, sr);
}
}
return remaining;
}
//Scans the memory pool and return the largest free space remaining
int largestFree(void)
{
int largest = 0;
int cur = 0;
for (int x = 0; x < poolSize; x++) {
//Increase cur if index value is null and set largest if cur is bigger
if (pool[x] == '\0') {
cur++;
if (cur > largest)
largest = cur;
}
else {
cur = 0;
//Get the integer value of the two size bytes
int sr = (int)pool[x];
int sl = (int)pool[x + 1];
//Jump from current index to end of allocation then continue
x = x + 1 + GetSize(sl, sr);
}
}
return largest;
}
//Scans the memory pool and return the smallest free space remaining
int smallestFree(void)
{
int smallest = poolSize;
int cur = 0;
for (int x = 0; x < poolSize; x++) {
if (pool[x] == '\0') {
cur++;
if (cur < smallest)
smallest = cur;
}
else {
cur = 0;
//Get the integer value of the two size bytes
int sr = (int)pool[x];
int sl = (int)pool[x + 1];
//Jump from current index to end of allocation then continue
x = x + 1 + GetSize(sl, sr);
}
}
return smallest;
}
T
have both space and alignment characteristics. You may be using size but have not considered alignment. Once memory is allocated you can't count on it having and particular value. So scanning for '\0' will not work in the general case. \$\endgroup\$pool[0]
\$\endgroup\$