<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Population</title>
</head>

<body>



<p align="center"><span lang="en-ca"><font size="6" color="#FF0000"><b>Memory 
Management</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca"> First </span>edition</font></b></pre>
</div>
<div align="left">
  <pre><b><font size="3">This is <span lang="en-ca">first</span></font><span lang="en-ca"><font size="3"> edition of my </font></span></b><span lang="en-ca"><font size="3"><b>memory management.</b></font></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>In the O.S. memory are just pieces of chunk of memory where several basic operations are implemented.</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>Allocate: a certain amount of memory are allocated by a certain searching policy. Release: memory are</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>returned to system and possibly needs to be merged with other consecutive free memory block.</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>Unused memory are chained up with doubly link list where a &quot;tag&quot; set at both beginning and end. Size</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>field appears at both ends, a pointer to previous and next unused memory. </b></font></span></pre>
</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>The manipulation of link list is a painful job! The 
  simulation of memory is using an array. Actually </b></span>
</div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>memory is considered to be linear. </b></span>
</div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>The code is no good as there are countless &quot;if else&quot; 
  which I hate most. And merge operation is a </b></span>
</div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>little bit tricky! Suppose you have one used chunk of 
  memory that you want to be released. It should</b></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>be merged with both side if they are free memory. Should 
  I tell you the detail of each bugs I found?</b></span></div>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<pre>#include &lt;iostream&gt;
#include &lt;time.h&gt;
#include &lt;iomanip&gt;

using namespace std;

const int MemLength=70;
const int MinFree=6;
const int MinUsed=3;

enum SearchPolicy
{FirstFit, WorstFit, BestFit};

enum MemType
{Free, Used};

class Mem
{
private:
	int memory[MemLength];
	int freeHead;
//	int usedHead;
	SearchPolicy searchPolicy;
	void doPrint(int usedLength, int freeLength, int pos);
	void initialize();
	bool firstFit(int&amp; index, int length);
	bool worstFit(int&amp; index, int length);
	bool bestFit(int&amp; index, int length);
	bool findFree(int&amp; index, int length);
	void doAllocate(int index, int length);
	int findNext(int index);
	bool canMerge(int index);
	void doMerge(int index);
	void insert(int index);
	void leftMerge(int index);
	void rightMerge(int index);
	void doubleMerge(int index);
public:
	Mem(SearchPolicy search=FirstFit);
	int allocate(int length);
	void release(int index);
	void print();
	
};

void doTest(Mem&amp; M, int lst[], int index)
{
	if (lst[index]!=-1)
	{
		M.release(lst[index]);
		cout&lt;&lt;&quot;\nnow print result after releasing &quot;&lt;&lt;index&lt;&lt;endl;
		M.print();
		lst[index]=-1;
	}
}

bool addTest(Mem&amp; M, int lst[], int index)
{
	int num=rand()%12+1;
	if (lst[index]==-1)
	{
		lst[index]=M.allocate(num);
		if (lst[index]==-1)
		{
			return false;
		}
		cout&lt;&lt;&quot;\nnow print for add size of&quot;&lt;&lt;num&lt;&lt;endl;
		M.print();
		return true;
	}
	return false;
}

const int Length=10;

int usedList[Length]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};

int main()
{	
	srand(time(0));

	
	Mem M(BestFit);
	for (int i=0; i&lt;Length;i++)
	{	
		addTest(M, usedList, i);		
	}
	cout&lt;&lt;&quot;\nnow release one by one\n&quot;;

	doTest(M, usedList, 2);
	doTest(M, usedList, 5);
	doTest(M, usedList, 0);
	cout&lt;&lt;&quot;\nnow show the best fit\n&quot;;
	while (!addTest(M, usedList, 2))
	{
	}

	/*
	for (i=0; i&lt;15; i++)
	{
		int index=rand()%10;
		doTest(M, usedList, index);
		index=rand()%10;
		addTest(M, usedList, index);
	}

	/*
	for (i=Length; i&gt;=0; i--)
	{
		int index=(i+4)%10;
		if (usedList[index]!=-1)
		{
			M.release(usedList[index]);
			cout&lt;&lt;&quot;\nnow print for &quot;&lt;&lt;i&lt;&lt;endl;
			M.print();
		}
	}
	*/
	cout&lt;&lt;endl;
	return 0;
}

void Mem::doubleMerge(int index)
{
	int leftSize=memory[index-2];
	int size=memory[index+1];
	int rightSize=memory[index+size+1];

	memory[index-leftSize+1]=memory[index+size+rightSize-2]=size+leftSize+rightSize;
	memory[index-leftSize+3]=memory[index+size+3];
}


bool Mem::canMerge(int index)
{
	bool result=false;
	int size=memory[index+1];//actual size
	if (index!=0)
	{
		result= result||memory[index-1]==Free;
	}
	if (index+size&lt;MemLength-1)
	{
		result=result||memory[index+size]==Free;
	}

	return result;
}


void Mem::leftMerge(int index)
{
	int size=memory[index+1];
	int leftSize=memory[index-2];
	memory[index-leftSize+1]=memory[index+size-2]=size+leftSize;
	memory[index+size-1]=memory[index-leftSize]=Free;

}

void Mem::rightMerge(int index)
{
	int size=memory[index+1];
	int rightSize;
	int prev, next;

	index+=size;//pointing to right head
	rightSize=memory[index+1];

	if (memory[index-1]==Free)//already leftMerged!
	{
		size=memory[index-2];//in case leftmerged!
	}
	memory[index-size+1]=memory[index+rightSize-2]=size+rightSize;
	memory[index+rightSize-1]=memory[index-size]=Free;
	prev=memory[index+2];
	next=memory[index+3];
	memory[index-size+2]=prev;
	memory[index-size+3]=next;
	memory[prev+3]=index-size;
	memory[next+2]=index-size;
	if (index==freeHead)
	{
		freeHead-=size;
	}
}



void Mem::doMerge(int index)
{
	int size=memory[index+1];
	if (index!=0)//possible of double merge
	{
		if (memory[index-1]==Free&amp;&amp;memory[index+size]==Free)
		{
			doubleMerge(index);
		}
		else
		{

			if (memory[index-1]==Free)
			{
				leftMerge(index);
			}
			if (memory[index+size]==Free)
			{
				rightMerge(index);
			}
		}
	}
	else//only possible of right merge
	{
		if (memory[index+size]==Free)
		{
			rightMerge(index);
		}
	}	
}
	
void Mem::insert(int index)
{
	int size=memory[index+1];
	int start=freeHead;
	int next;
	//this won't change
	memory[index]=memory[index+size-1]=Free;
	memory[index+size-2]=size;

	//empty list
	if (freeHead==-1)
	{
		freeHead=index;
		memory[index+2]=0;//no prev
		memory[index+3]=0;
		return ;
	}
	next=memory[start+3];
	//right before everything
	if (start&gt;index)
	{
		freeHead=index;
		memory[index+2]=0;//no prev
		memory[index+3]=start;
		memory[start+2]=index;
		return;
	}
	while(start&lt;index&amp;&amp;next&lt;index&amp;&amp;next!=0)
	{
		start=next;
		next=memory[start+3];
	}

	memory[start+3]=index;//next of prev
	if (next!=0)
	{
		memory[next+2]=index;//prev of next
	}

	memory[index+2]=start;
	memory[index+3]=next;
}

void Mem::release(int index)
{
	if (canMerge(index))
	{
		doMerge(index);
	}
	else
	{
		insert(index);
	}
}

int Mem::findNext(int index)
{
	return memory[index+3];
}

Mem::Mem(SearchPolicy search)
{
	searchPolicy = search;
	initialize();
}

bool Mem::firstFit(int&amp; index, int length)
{
	index=freeHead;
	do 
	{
		if (memory[index+1]&gt;length+MinUsed)
		{
			return true;
		}

	}while ((index=findNext(index))!=0);
	return false;
}


bool Mem::findFree(int&amp; index, int length)
{
	switch (searchPolicy)
	{
	case FirstFit:
		return firstFit(index, length);
	case WorstFit:
		return worstFit(index, length);
	case BestFit:
		return bestFit(index, length);
	}
	return false;
}

void Mem::doAllocate(int index, int length)
{
	int prev, next, size;

	size=memory[index+1];//old size
	prev=memory[index+2];
	next=memory[index+3];

	//set up free old 
	if (size-length&gt;MinFree)
	{
		memory[index+length]=Free;
		memory[index+length+1]=memory[index+size-2]=size-length;
		memory[index+length+2]=prev;
		memory[index+length+3]=next;
		memory[next+2]=index+length;//update next node

		memory[index]=memory[index+length-1]=Used;
		memory[index+1]=length;
		if (index==freeHead)
		{
			freeHead+=length;
		}
		else
		{
			memory[prev+3]=index+length;
		}
		if (next!=0)
		{
			memory[next+2]=index+length;
		}
	}
	else
	{
		//allocate all free mem
		memory[index+1]=size;
		memory[index]=memory[index+size-1]=Used;
		if (next!=0)
		{
			memory[next+2]=prev;//next has no prev
		


			if (index==freeHead)
			{
				freeHead=next;
			}
		}
		else
		{
			if (index==freeHead)//empty list
			{
				freeHead=-1;
			}
		}
		if (prev!=0)
		{
			memory[prev+3]=next;
		}

	}	

}

bool Mem::bestFit(int&amp; index, int length)
{	
	int min=-1, size, result=freeHead;
	index=freeHead;
	if (index==-1)
	{
		return false;
	}
	do 
	{
		if ((size=memory[index+1]-length-MinUsed)&gt;=0)
		{
			if (min&gt;=0&amp;&amp;size&lt;min)
			{
				min=size;
				result=index;
			}
			else
			{
				if (min&lt;0)//not initialized
				{
					min = size;//first time
					result=index;
				}
			}		
		}
	}while ((index=findNext(index))!=0);
	if (min&gt;=0)
	{
		index=result;
		return true;
	}
	else
	{
		return false;
	}
}

bool Mem::worstFit(int&amp; index, int length)
{
	int max=-1, size, result;
	index=freeHead;
	if (index==-1)
	{
		return false;
	}
	do 
	{
		if ((size=memory[index+1]-length-MinUsed)&gt;=0)
		{
			if (max&gt;=0&amp;&amp;size&gt;max)
			{
				max=size;
				result=index;
			}
			else
			{
				if (max&lt;0)//not initialized
				{
					max = size;//first time
					result=index;
				}
			}		
		}
	}while ((index=findNext(index))!=0);
	if (max&gt;=0)
	{
		index=result;
		return true;
	}
	else
	{
		return false;
	}
}

int Mem::allocate(int length)
{
	int index=freeHead;
	if (findFree(index, length))
	{
		doAllocate(index, length+MinUsed);//allocate more

		return index;
	}
	else
	{
		return -1;
	}
}

void Mem::doPrint(int usedLength, int freeLength, int pos)
{
	int limit=pos+usedLength;
	int length=memory[pos+1];
	while (pos&lt;limit)
	{
		cout&lt;&lt;setw(2)&lt;&lt;memory[pos+1];
		for (int i=2; i&lt;length; i++)
		{		
			cout&lt;&lt;'*';		
		}
		pos+=length;
		length=memory[pos+1];
	}
	if (freeLength!=0)
	{
		cout&lt;&lt;setw(2)&lt;&lt;memory[pos+1];
		for (int i=2; i&lt;freeLength; i++)
		{
			cout&lt;&lt;' ';	
		}
	}
}

void Mem::print()
{
	int index=freeHead;
	int pos=0;
	int usedLength;
	int freeLength;
	if (freeHead==-1)
	{
		doPrint(MemLength, 0, 0);
		return;
	}
	while (true)
	{		
		usedLength=index-pos;
		freeLength=memory[index+1];
		doPrint(usedLength, freeLength, pos);
		pos+=usedLength;
		pos+=freeLength;
		if (memory[index+3]==0||pos==MemLength)
		{
			if (pos&lt;MemLength-1)//print extra used chunk
			{
				freeLength=0;
				usedLength=MemLength-pos-1;
				doPrint(usedLength, freeLength, pos);
			}
			return;
		}
		else
		{
			index=memory[index+3];
		}
	}

}

void Mem::initialize()
{
	memory[0]=memory[MemLength-1]=Free;
	memory[1]=memory[MemLength-2]=MemLength;
	memory[2]=0;//the prev
	memory[3]=0;//the next
	freeHead=0;//pointing to the head;	
}



</pre>
<pre>
</pre>
<pre></pre>
<pre><font color="#0000FF"><b>Here is the result:<span lang="en-ca">(Note DFS and BFS gives almost opposite result.)</span></b></font></pre>
<pre>
now print for add size of10
13***********57
now print for add size of2
13*********** 5***52
now print for add size of2
13*********** 5*** 5***47
now print for add size of10
13*********** 5*** 5***13***********34
now print for add size of2
13*********** 5*** 5***13*********** 5***29
now print for add size of5
13*********** 5*** 5***13*********** 5*** 8******21
now print for add size of3
13*********** 5*** 5***13*********** 5*** 8****** 6****15
now print for add size of7
13*********** 5*** 5***13*********** 5*** 8****** 6****15*************
now release one by one

now print result after releasing 2
13*********** 5*** 5 13*********** 5*** 8****** 6****15*************
now print result after releasing 5
13*********** 5*** 5 13*********** 5*** 8 6****15*************
now print result after releasing 0
13 5*** 5 13*********** 5*** 8 6****15*************
now show the best fit

now print for add size of4
13 5*** 5 13*********** 5*** 8****** 6****15*************
Press any key to continue</pre>

<pre></pre>

<pre></pre>
<pre>	
</pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="WhoAmI.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>