Google Advertisement

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

Google Advertisement
πŸ”₯ 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

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:

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?

Google Advertisement

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

Google Advertisement

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

  • Google Advertisement

    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.

❀️ Like πŸ’¬ Comment πŸ”— Share
Google Advertisement
πŸ‘‰ View Full Version on Main Website β†—
Google Advertisement
πŸ‘‰ Read Full Article on Website