142. Static Object Pool

#include <iostream>
#include <string>

struct Message {
    int id;
};

class MessagePool {
private:
    // The actual storage for objects
    static Message pool[3];
    // Flags to track which slots are taken
    static bool in_use[3];

public:
    static Message* allocate() {
        // Linear search for a free slot
        for (int i = 0; i < 3; ++i) {
            if (!in_use[i]) {
                in_use[i] = true; // Mark as taken
                return &pool[i];  // Return address of the slot
            }
        }
        return nullptr; // No slots available
    }

    static void release(Message* m) {
        // Pointer arithmetic: (address of m) - (start of array) = index
        int index = m - pool;
        
        // Safety check to ensure pointer belongs to this pool
        if (index >= 0 && index < 3) {
            in_use[index] = false; // Mark as free
        }
    }

    static Message* getSlot(int index) {
        if (index >= 0 && index < 3) return &pool[index];
        return nullptr;
    }

    static int getIndex(Message* m) {
        return m - pool;
    }
};

// Definition of static members
Message MessagePool::pool[3];
bool MessagePool::in_use[3] = {false, false, false};

int main() {
    int N;
    if (!(std::cin >> N)) return 0;

    for (int i = 0; i < N; ++i) {
        std::string cmd;
        std::cin >> cmd;

        if (cmd == "ALLOC") {
            int id;
            std::cin >> id;
            Message* m = MessagePool::allocate();
            if (m) {
                m->id = id;
                std::cout << "Allocated Slot " << MessagePool::getIndex(m) << std::endl;
            } else {
                std::cout << "Pool Full" << std::endl;
            }
        } else if (cmd == "FREE") {
            int idx;
            std::cin >> idx;
            Message* m = MessagePool::getSlot(idx);
            if (m) {
                MessagePool::release(m);
                std::cout << "Freed Slot " << idx << std::endl;
            }
        }
    }
    return 0;
}

Explanation & Logic Summary:

  • O(1) Memory: The memory usage is constant (3 objects). It never grows, ensuring we never run out of RAM unexpectedly.
  • O(N) Allocation: Finding a free slot takes linear time relative to the pool size (checking flags). For small pools (size < 32), this is extremely fast.
  • Pointer Arithmetic: m - pool is a standard C++ feature. It subtracts the memory addresses and divides by sizeof(Message), returning the integer index of the array element. This allows us to map a pointer back to its flag in_use[index].

Firmware Relevance & Real-World Context:

  • Real-Time OS (RTOS): This is exactly how "Memory Pools" or "Mailboxes" work in FreeRTOS or ThreadX.
  • CAN Bus Buffers: A CAN controller might have 3 hardware transmit mailboxes. A driver uses a pool like this to track which mailboxes are busy sending and which are free to accept a new frame.

 

 

 

 

Loading...

Input

5 ALLOC 100 ALLOC 200 ALLOC 300 ALLOC 400 FREE 1

Expected Output

Allocated Slot 0 Allocated Slot 1 Allocated Slot 2 Pool Full Freed Slot 1