Smart Memory Management in OS: Simulator using First Fit, Best Fit & Worst Fit

๐Ÿ”ฅ Read with Full Features on Our Website

Learn how to build a memory management simulator in C++ using First Fit, Best Fit, and Worst Fit strategies. Understand every step with simple explanations and source code.

Published on 13 May 2025
By Vandu

Implement a Memory Management Simulator Using First Fit, Best Fit, and Worst Fit

๐Ÿ”ฅ Read with Full Features on Our Website

Memory management is a crucial part of any operating system. It decides how memory is allocated and deallocated to processes. There are different memory allocation strategies like:

  • First Fit

  • Best Fit

  • Worst Fit

In this tutorial, we’ll create a simple memory management simulator in C++ that uses these three strategies. We'll explain each step in easy words with code so you can understand and implement it on your own.


Google Advertisement

๐Ÿ“Œ What Is Memory Allocation in Operating Systems?

When programs run, they need memory (RAM) to store data and instructions. The Operating System (OS) decides how to divide this memory among multiple programs. If not done efficiently, some memory might be wasted or some programs might not run properly.

To solve this, different memory allocation strategies are used:

  • First Fit: Allocate the first memory block that is large enough.

  • Best Fit: Allocate the smallest memory block that is big enough (to reduce wastage).

  • Worst Fit: Allocate the largest memory block (to leave big chunks behind).


๐Ÿงฉ Let's Build the Simulator

We’ll simulate a memory of fixed size and allow the user to request memory for different processes. We'll apply each strategy and show how memory is allocated.

๐Ÿ› ๏ธ Step 1: Include Required Libraries

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

๐Ÿงฑ Step 2: Define Structures

We’ll define a structure for memory blocks and processes.

struct Block {
    int id;
    int size;
    bool allocated;
};

struct Process {
    int id;
    int size;
    int blockAllocated;
};
 

๐Ÿ—ƒ๏ธ Step 3: Input Memory Blocks and Processes

void inputBlocks(vector<Block> &blocks, int n) {
    for (int i = 0; i < n; i++) {
        int size;
        cout << "Enter size of block " << i + 1 << ": ";
        cin >> size;
        blocks.push_back({i + 1, size, false});
    }
}

void inputProcesses(vector<Process> &processes, int m) {
    for (int i = 0; i < m; i++) {
        int size;
        cout << "Enter size of process " << i + 1 << ": ";
        cin >> size;
        processes.push_back({i + 1, size, -1});
    }
}
 

Google Advertisement

1๏ธโƒฃ First Fit Algorithm

๐Ÿ‘‡ Code

void firstFit(vector<Block> blocks, vector<Process> processes) {
    cout << "\n--- First Fit Allocation ---\n";
    for (auto &p : processes) {
        for (auto &b : blocks) {
            if (!b.allocated && b.size >= p.size) {
                p.blockAllocated = b.id;
                b.allocated = true;
                break;
            }
        }
    }

    for (auto &p : processes) {
        if (p.blockAllocated != -1)
            cout << "Process " << p.id << " allocated to Block " << p.blockAllocated << endl;
        else
            cout << "Process " << p.id << " not allocated\n";
    }
}
 

โœ… Explanation

  • We go through each process and check every block.

  • If the block is not allocated and has enough space, we allocate it immediately.

  • This is the "First Fit" strategy — assign the first available suitable block.


2๏ธโƒฃ Best Fit Algorithm

๐Ÿ‘‡ Code

void bestFit(vector<Block> blocks, vector<Process> processes) {
    cout << "\n--- Best Fit Allocation ---\n";
    for (auto &p : processes) {
        int bestIdx = -1;
        for (int i = 0; i < blocks.size(); i++) {
            if (!blocks[i].allocated && blocks[i].size >= p.size) {
                if (bestIdx == -1 || blocks[i].size < blocks[bestIdx].size)
                    bestIdx = i;
            }
        }
        if (bestIdx != -1) {
            blocks[bestIdx].allocated = true;
            p.blockAllocated = blocks[bestIdx].id;
        }
    }

    for (auto &p : processes) {
        if (p.blockAllocated != -1)
            cout << "Process " << p.id << " allocated to Block " << p.blockAllocated << endl;
        else
            cout << "Process " << p.id << " not allocated\n";
    }
}
 

โœ… Explanation

  • We search for the smallest available block that is large enough for the process.

  • Among all suitable blocks, we pick the best (smallest) fit.


3๏ธโƒฃ Worst Fit Algorithm

๐Ÿ‘‡ Code

Google Advertisement
void worstFit(vector<Block> blocks, vector<Process> processes) {
    cout << "\n--- Worst Fit Allocation ---\n";
    for (auto &p : processes) {
        int worstIdx = -1;
        for (int i = 0; i < blocks.size(); i++) {
            if (!blocks[i].allocated && blocks[i].size >= p.size) {
                if (worstIdx == -1 || blocks[i].size > blocks[worstIdx].size)
                    worstIdx = i;
            }
        }
        if (worstIdx != -1) {
            blocks[worstIdx].allocated = true;
            p.blockAllocated = blocks[worstIdx].id;
        }
    }

    for (auto &p : processes) {
        if (p.blockAllocated != -1)
            cout << "Process " << p.id << " allocated to Block " << p.blockAllocated << endl;
        else
            cout << "Process " << p.id << " not allocated\n";
    }
}
 

โœ… Explanation

  • We look for the largest available block.

  • This strategy tries to avoid leaving behind small fragments of memory.


๐Ÿงช Final: Main Function to Run the Simulator

int main() {
    vector<Block> blocks;
    vector<Process> processes;
    int n, m;

    cout << "Enter number of memory blocks: ";
    cin >> n;
    inputBlocks(blocks, n);

    cout << "Enter number of processes: ";
    cin >> m;
    inputProcesses(processes, m);

    firstFit(blocks, processes);
    bestFit(blocks, processes);
    worstFit(blocks, processes);

    return 0;
}
 

๐Ÿง  Summary Table of Algorithms

Strategy Best For Drawback
First Fit Fast and simple May cause fragmentation
Best Fit Reduces memory waste Can be slow due to searching
Worst Fit Leaves large blocks behind May increase fragmentation

๐ŸŽฏ Conclusion

In this article, we created a simple memory allocation simulator using C++. We used:

  • First Fit: Fastest, less efficient.

  • Best Fit: More efficient but slower.

  • Worst Fit: May seem counter-intuitive but useful in specific cases.

Each strategy has its own strengths and weaknesses. Understanding these helps in designing better operating systems or applications that handle memory efficiently.

๐Ÿ‘‰ View Full Version on Main Website โ†—
๐Ÿ‘‰ Read Full Article on Website