⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ram.cpp

📁 通过程序完成动态分区存储管理方式的内存分配与回收.
💻 CPP
字号:
// ram.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"
#include <stdio.h>


void InitializeRAM(HWND);
void ShowRAM(void);
void CreateEditRect(char *, int);
void GetEditInt(void);
#define BUTTONID	10000
#define FF_RAM 0
#define BF_RAM 1
int AllocateAlgorithm;
HWND hWind;

#define MAXRAMSIZE 256
#define MAXAREANO   15
#define MAXPROCESSNO 100

//定义空闲分区表
struct {
	int Address;
	int Length;
}FreeAreaList[MAXAREANO];

//定义进程内存分配表
struct {
	int Flag;
	int Address;
	int Length;
}ProcessList[MAXPROCESSNO];

void Allocate_FF_RAM(int);
void Allocate_BF_RAM(int);

int FreeAreaMaxNo;	//空闲分区最大数目
int ProcessMaxNo;	//进程最大数目
HDC RAM_DC;

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];								// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];								// The title bar text

// Foward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_RAM, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_RAM);

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_RAM);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_RAM;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR szHello[MAX_LOADSTRING];
	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

	switch (message) 
	{	
		case WM_CREATE: //insert
			InitializeRAM(hWnd);
			break;
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			// Parse the menu selections:
			switch (wmId)
			{
				case IDM_ABOUT:
				   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
				   break;
				case IDM_EXIT:
				   DestroyWindow(hWnd);
				   break;
			case IDM_RAMALLOCATE:
				CreateEditRect("请输入进程长度:", IDM_RAMALLOCATE);
				break;
			case IDM_RAMFREE:
				CreateEditRect("请输入撤销进程:", IDM_RAMFREE);
				break;
			case IDM_ALLOCATE_FF_RAM:
				AllocateAlgorithm = FF_RAM;
				ShowRAM();
				break;
			case IDM_ALLOCATE_BF_RAM:
				AllocateAlgorithm = BF_RAM;
				ShowRAM();
				break;
			case BUTTONID:
				GetEditInt();
				break;
			default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			// TODO: Add any drawing code here...
			RECT rt;
			GetClientRect(hWnd, &rt);
			ShowRAM();
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
				return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
			{
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}




//--------------------------------------------------------
//	动态分区内存分配与回收之初始化函数
//--------------------------------------------------------
void InitializeRAM(HWND hWnd)
{
	FreeAreaMaxNo=1	;			//空闲分区数目1个
	ProcessMaxNo= 0	;			//进程数目0个
	FreeAreaList[0].Address =0 ;		//第0空闲分区首址
	FreeAreaList[0].Length = MAXRAMSIZE;	//第0空闲分区大小
	AllocateAlgorithm = FF_RAM;		//内存分区分配算法设置为首次适应算法

	hWind=hWnd;
	RAM_DC = GetDC(hWnd);
}
//---------------------------------------------------------
// 显示空闲分区标及内存分配表
//---------------------------------------------------------
RECT RAMRect= {700,100,900,100+2*MAXRAMSIZE};
RECT AreaRect = {400,130,460,130+30};
void ShowRAM()
{
	int i;
	char ProcessString[32],FreeAreaString[3][32];
	HBRUSH ProcessBrush;
	RECT ProcessRect,faRect;

	if(AllocateAlgorithm == FF_RAM)
		SetWindowText(hWind,"动态分区分配实验---采用首次适应算法分配内存");
	if(AllocateAlgorithm == BF_RAM)
		SetWindowText(hWind,"动态分区分配实验---采用最佳适应算法分配内存");

	ProcessRect = RAMRect;
	TextOut(RAM_DC,ProcessRect.right+4,ProcessRect.top-8,"0K",2);
	wsprintf(ProcessString,"%dK",MAXRAMSIZE);
	TextOut(RAM_DC,RAMRect.right+4,ProcessRect.top-8+2*MAXRAMSIZE,
		ProcessString,strlen(ProcessString));
	Rectangle(RAM_DC,RAMRect.left-2,RAMRect.top-2,RAMRect.right+2,RAMRect.bottom+2);

	for(i=0;i<ProcessMaxNo;i++)
	{
		if(ProcessList[i].Flag != 0)
		{
			ProcessRect = RAMRect;
			ProcessRect.top = ProcessRect.top + 2*ProcessList[i].Address;
			ProcessRect.bottom = ProcessRect.top + 2*ProcessList[i].Length;
			Rectangle(RAM_DC,ProcessRect.left-1,ProcessRect.top-1,
				ProcessRect.right+1,ProcessRect.bottom+1);
			ProcessBrush = CreateSolidBrush(RGB(255,255,0));
			FillRect(RAM_DC,&ProcessRect,ProcessBrush);
			DeleteObject(ProcessBrush);

			wsprintf(ProcessString,"%dK",ProcessList[i].Address);
			TextOut(RAM_DC,ProcessRect.right+4,ProcessRect.top-8,
				ProcessString,strlen(ProcessString));
			wsprintf(ProcessString,"%dK",ProcessList[i].Address+ProcessList[i].Length);
			TextOut(RAM_DC,ProcessRect.right+4,ProcessRect.top-8+2*ProcessList[i].Length,
				ProcessString,strlen(ProcessString));
			wsprintf(ProcessString,"进程%d = %dK",i,ProcessList[i].Length);
			ProcessRect.top += ProcessList[i].Length - 8;
			DrawText(RAM_DC,ProcessString,strlen(ProcessString),&ProcessRect,DT_CENTER);
		}
	}

	TextOut(RAM_DC,AreaRect.left+60,AreaRect.top-60,
		"空闲分区表",10);
	TextOut(RAM_DC,AreaRect.left+380,AreaRect.top-60,
		"内存",4);
	for(i=-1;i<FreeAreaMaxNo;i++)
	{
		if(i==-1)
		{
			strcpy(FreeAreaString[0],"分区号");
			strcpy(FreeAreaString[1],"分区首址");
			strcpy(FreeAreaString[2],"分区大小");
		}
		else
		{
			wsprintf(FreeAreaString[0],"%d",i);
			wsprintf(FreeAreaString[1],"%d",FreeAreaList[i].Address);
			wsprintf(FreeAreaString[2],"%d",FreeAreaList[i].Length);
		}

		faRect = AreaRect;
		faRect.top		+= i*29;
		faRect.bottom	+= i*29;
		Rectangle(RAM_DC,faRect.left,faRect.top,faRect.right,faRect.bottom);
		TextOut(RAM_DC,faRect.left/2+faRect.right/2-strlen(FreeAreaString[0])*4,
			faRect.top+6,FreeAreaString[0],strlen(FreeAreaString[0]));

		faRect.left		+= 59;
		faRect.right	+= 80;
		Rectangle(RAM_DC,faRect.left,faRect.top,faRect.right,faRect.bottom);
		TextOut(RAM_DC,faRect.left/2+faRect.right/2-strlen(FreeAreaString[1])*4,
			faRect.top+6,FreeAreaString[1],strlen(FreeAreaString[1]));

		faRect.left += 80;
		faRect.right += 80;
		Rectangle(RAM_DC,faRect.left,faRect.top,faRect.right,faRect.bottom);
		TextOut(RAM_DC,faRect.left/2+faRect.right/2-strlen(FreeAreaString[2])*4,
			faRect.top+6,FreeAreaString[2],strlen(FreeAreaString[2]));
	}
}
	//-------------------------------------------------------------------------
	//  	内存分配函数
	//-------------------------------------------------------------------------
	
	void AllocateRAM(int AllocatRamSize)
	{
	int i,j,faID,bfSize;

	if(AllocateAlgorithm == FF_RAM){ 	//首次适应算法
		for(i=0;i<FreeAreaMaxNo;i++){
			if(FreeAreaList[i].Length >=AllocatRamSize)break;
		}
	}
	if(AllocateAlgorithm ==BF_RAM){		//最佳适应算法
		faID =FreeAreaMaxNo;
		bfSize=MAXRAMSIZE;
		for(i=0;i<FreeAreaMaxNo;i++){
			if(FreeAreaList[i].Length >=AllocatRamSize){
				if(bfSize>=FreeAreaList[i].Length-AllocatRamSize){
				faID=i;
				bfSize=FreeAreaList[i].Length-AllocatRamSize;
			}
		}
	}
	i=faID;
	}
		
	if(i>=FreeAreaMaxNo){
		MessageBox(NULL,"进程需要内存太多,没有足够内存可供分配!",NULL,MB_OK);
		return;
	}
	
	ProcessList[ProcessMaxNo].Flag =1 ;
	ProcessList[ProcessMaxNo].Address = FreeAreaList[i].Address; //进程内存首址
	ProcessList[ProcessMaxNo].Length = AllocatRamSize;
	ProcessMaxNo++;

	FreeAreaList[i].Address +=AllocatRamSize;		//空闲分区首址
	FreeAreaList[i].Length -=AllocatRamSize;		//空闲分区大小
	if(FreeAreaList[i].Length ==0){				//如果空闲分区大小为0,撤销
		for(j=i;j<FreeAreaMaxNo-1;j++){
		FreeAreaList[i].Address =FreeAreaList[j+1].Address;
		FreeAreaList[j].Length = FreeAreaList[j+1].Length;
	}
	FreeAreaMaxNo--;
	}
	
	InvalidateRect(hWind,NULL,TRUE);
	UpdateWindow(hWind);
	ShowRAM();
	}
//------------------------------------------------------------------
//	内存回收函数
//------------------------------------------------------------------

	void FreeRAM(int ProcessID)
	{
		int i,j;
		char FreeString[32];
		int Address,Length;
		
		if(ProcessID>MAXPROCESSNO){
			MessageBox(NULL,"进程号太大,没有这个进程!",NULL,MB_OK);
			return;
		}
		if(ProcessList[ProcessID].Flag ==0){
			wsprintf(FreeString,"进程%d不存在!",ProcessID);
			MessageBox(NULL,FreeString,NULL,MB_OK);
			return;
		}
		ProcessList[ProcessID].Flag=0;
		Address =ProcessList[ProcessID].Address;
		Length = ProcessList[ProcessID].Length;//与上边分区相邻
			
			
			for(i=0; i<FreeAreaMaxNo;i++){
				if(FreeAreaList[i].Address+FreeAreaList[i].Length==Address){//与上边分区相邻
					FreeAreaList[i].Length += Length;
					if(FreeAreaList[i].Address+FreeAreaList[i].Length !=FreeAreaList[i+1].Address)
						goto ShowRAMLoop;
					FreeAreaList[i].Length += FreeAreaList[i+1].Length;//与上下边分区皆相邻
					for(j=i+1;j<FreeAreaMaxNo-1;j++){//撤销下边分区项
						FreeAreaList[j].Address =FreeAreaList[j+1].Address;
						FreeAreaList[j].Length = FreeAreaList[j+1].Length;
					}
					FreeAreaMaxNo--;
					goto 	ShowRAMLoop;
				}
				if(Address+Length==FreeAreaList[i].Address){	//与下边分区相邻,合并
					FreeAreaList[i].Address=Address;//?
					FreeAreaList[i].Length+=Length;
					goto ShowRAMLoop;
				}
			}
			for(i=FreeAreaMaxNo;i>0;i--){//上下都没有空闲分区相邻
				if(FreeAreaList[i-1].Address<Address)break;
				FreeAreaList[i].Address= FreeAreaList[i-1].Address;
				FreeAreaList[i].Length = FreeAreaList[i-1].Length;
			}
			FreeAreaList[i].Address = Address;
			FreeAreaList[i].Length =Length;
			FreeAreaMaxNo++;
			
ShowRAMLoop:
			InvalidateRect(hWind,NULL,TRUE);
			UpdateWindow(hWind);
			ShowRAM();
	}
		//----------------------------------------------------
		//数据输入函数
		//----------------------------------------------------
		
HWND hEdit, hButton;
RECT hEditRect ={170,100,300,130};
int AllocFreeID;
void CreateEditRect(char *EditStatic,int afID)
{
	AllocFreeID=afID;
	TextOut(RAM_DC,hEditRect.left-120,hEditRect.top+4,EditStatic,strlen(EditStatic));
	hEdit = CreateWindow("EDIT",NULL,WS_CHILD|WS_VISIBLE|ES_LEFT|WS_THICKFRAME,
		hEditRect.left,hEditRect.top, hEditRect.right-hEditRect.left,
		hEditRect.bottom-hEditRect.top,hWind,NULL,hInst,NULL);//生成编辑
	hButton = CreateWindow("BUTTON","确定",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
		hEditRect.left-50,hEditRect.top+60,hEditRect.right-hEditRect.left-40,
		hEditRect.bottom-hEditRect.top,hWind,(HMENU)BUTTONID,hInst,NULL);//确定生成
}
//--------------------------------------------------------------
//	获取数据函数
//--------------------------------------------------------------
void GetEditInt()
{
	char hEditString[16];
	int hEditInt;
	
	GetWindowText(hEdit,hEditString,15);
	hEditInt = atoi(hEditString);
	DestroyWindow(hEdit);
	DestroyWindow(hButton);
	if(AllocFreeID==IDM_RAMALLOCATE) AllocateRAM(hEditInt);
	if(AllocFreeID==IDM_RAMFREE)	FreeRAM(hEditInt);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -