Unique Pointer Custom Deleter

#include <iostream>
#include <cstdint>
#include <memory>

using namespace std;

class DataBlock {
public:
    uint8_t* buf1;
    uint8_t* buf2;
    int size;

    DataBlock(int n) : size(n) {
        buf1 = new uint8_t[n];
        buf2 = new uint8_t[n];
    }

    // Note: In a real scenario, we'd disable copy constructor/assignment
    // to prevent double-freeing if not using smart pointers.

    void set(int index, uint8_t value) {
        buf1[index] = value;
        buf2[index] = value;
    }

    void print() const {
        for (int i = 0; i < size; i++) {
            cout << (int)buf1[i];
            if (i != size - 1) cout << " ";
        }
        cout << endl;
    }
};

// Factory function creates object dynamically
DataBlock* createDataBlock(int n) {
    return new DataBlock(n);
}

// Custom cleanup function — must be used
void cleanup(DataBlock* p) {
    if (p) {
        delete[] p->buf1;
        delete[] p->buf2;
        delete p;
        cout << "Object cleaned" << endl;
    }
}

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

    {
        /**
         * 1. Declare the unique_ptr with a custom deleter type.
         * The syntax is: std::unique_ptr<Type, DeleterType>
         * 2. Pass the cleanup function to the constructor.
         */
        std::unique_ptr<DataBlock, void(*)(DataBlock*)> ptr(createDataBlock(N), cleanup);

        for (int i = 0; i < N; i++) {
            int temp;
            cin >> temp;
            // Use the -> operator to access members of the managed object
            ptr->set(i, static_cast<uint8_t>(temp));
        }

        // Print object data
        ptr->print();
        
        // Scope ends here: cleanup(ptr.get()) is called automatically.
    }

    return 0;
}

Solving Approach

 

 

 

 

 

Upvote
Downvote
Loading...

Input

1 0

Expected Output

0 Object cleaned