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

By Vandu
May 13, 2025

Follow us on


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.

Smart Memory Management in OS: Simulator using First Fit, Best Fit & Worst FitImplement a Memory Management Simulator Using First Fit, Best Fit, and Worst Fit

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.


📌 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});
    }
}
 

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

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.


© 2025 Pay18News. All rights reserved.