My functions are working pretty good.
MyMalloc checks that an allocation is either a perfect fit (length=n), or that any remainder block length will be >= 1 (don't want any zero length blocks, or to overwrite next manage variable). This version handles that:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
short* MyMalloc( unsigned short n )
{
unsigned short i = 0;
while( i < size )
{
short data = buff[i];
bool available = false;
if( data < 0 )
{
available = true;
data *= -1;
}
unsigned short length = (unsigned short)data;
if( available && (length >= n) )// allocate!
{
if( length > n + 1 )// so that remaining block length >= 1
{
buff[i+n+1] = -1*(length - (n+1));
buff[i] = (short)n;
return buff+i+1;
}
if( length == n )// exact fit. Merely reclaim
{
buff[i] *= -1;
return buff+i+1;
}
}
i += length + 1;
}
return NULL;
}
|
MyFree is doing free block coalescence well, but I think I have an off-by-one error when freeing the last allocated block (which is actually a coalescence operation with the remainder of buff. Lines 25 to 27 below execute). More testing needed. Freeing all blocks leaves buff[0] = -500 but should = -499 (initial value).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
bool MyFree( short* pBlock )
{
short i = 0;
short iPrev = 0;
short iNext = 0;
while( i < size )
{
short length = buff[i]<0 ? -buff[i] : buff[i];
iNext = i + length + 1;
if( (buff[i] > 0) && (pBlock == (buff+i+1)) )// free this block
{
// 4 cases
if( (i>0) && (buff[iPrev]<0) && (buff[iNext]<0) )// free all 3 blocks
{
buff[iPrev] = -1*( (iNext - iPrev) - buff[iNext] + 1 );
if( (iNext - buff[iNext]) >= size )
buff[iPrev] += 1;// due to coalescence with end
}
else if( (i>0) && (buff[iPrev]<0) )// free prev + this block
buff[iPrev] = (iPrev - iNext) + 1;
else if( buff[iNext] < 0 )// free this + next block
{
buff[i] = buff[iNext] + i - iNext;
if( (iNext - buff[iNext]) >= size )
buff[i] += 1;// due to coalescence with end
}
else// free this block only
buff[i] *= -1;
return true;
}
iPrev = i;
i = iNext;
}
return false;
}
|
EDIT 1: Lines 6 through 13 in MyMalloc are embarrassing. I won't try to fix it here, but I'm struggling with combining usage of signed and unsigned types there.
Edit 2: I have arrived at an answer to this question of yours from several posts ago:
What do I need in order to prevent using " buff[0] = size " in main().
I need to send only MyMalloc and MyFree without main(), so what can I do in order to manage the first cell?
|
At first I was confused about the issue, but I think I see it now.
Answer: Switch to C++ so you can use objects which have constructors.
HAH!
EDIT 3: Some further musings about C++.
My technical background started via a youthful interest in physics. I was (forcibly) introduced to programming in two intro courses (Pascal) required for my B.S. in physics.
Hobbying took me to c for years. I like nice clean procedural programming too. Consider the overall simplicity of the current solution method vs. the template class based solution I was working on earlier in this thread.
That said however (here comes the C++ pitch),...
Virtual functions?
Template classes?
Function overloading?
Operator overloading?
OOP, in general?
...and so on...
I am astounded at the depth (and beauty) of the abstraction present in the language model.
I
never expected to encounter this outside the fields of mathematics and physics.