vendredi 8 janvier 2021

What to give a function that expects a raw pointer?

I'm using a library that, in order to construct some object that I use, expects a raw pointer to an object. I'm not sure what it will do with the pointer, to make my code as safe as possible, what should I pass to this function?

  1. Use a unique pointer - if they decide to delete the pointer, I will do a double-delete
  2. Keep track of a raw pointer - bad because I have to remember to write delete, but it could still be a double-delete
  3. Use auto duration and give them a pointer Give them a reference - their code will error if they call delete
  4. Use a shared pointer - same double-delete problem as unique pointer, but now my scope won't hurt their pointer

Based on my reading, option 3 seems like what I should do - they shouldn't be calling delete on the pointer, and this format enforces that. But what if I don't know whether they now or in the future will call delete on the reference I gave them? Use a shared pointer and say "not my fault about the double delete"?

#include <memory>
#include <iostream>

class ComplexObj {
  public:
    ComplexObj() : m_field(0) {}
    ComplexObj(int data) : m_field(data) {}

    void print() { std::cout << m_field << std::endl; }

  private:
    int m_field;
};

class BlackBox {
  public:
    BlackBox(ComplexObj* data) {
        m_field = *data;

        // Do other things I guess...

        delete data;
        std::cout << "Construction complete" << std::endl;
    }

    void print_data() { m_field.print(); }

  private:
    ComplexObj m_field;
};

int main(int argc, char* argv[]) {
    // Use a smart pointer
    std::unique_ptr<ComplexObj> my_ptr(new ComplexObj(1));
    BlackBox obj1 = BlackBox(my_ptr.get());
    obj1.print_data();
    my_ptr->print();  // Bad data, since BlackBox free'd
    // double delete when my_ptr goes out of scope

    // Manually manage the memory
    ComplexObj* manual = new ComplexObj(2);
    BlackBox obj2 = BlackBox(manual);
    obj2.print_data();
    manual->print();  // Bad data, since BlackBox free'd
    delete manual;    // Pair new and delete, but this is a double delete

    // Edit: use auto-duration and give them a pointer
    ComplexObj by_ref(3);
    BlackBox obj3 = BlackBox(&by_ref);  // they can't call delete on the pointer they have
    obj3.print_data();
    by_ref.print();

    // Use a shared pointer
    std::shared_ptr<ComplexObj> our_ptr(new ComplexObj(4));
    BlackBox obj4 = BlackBox(our_ptr.get());
    obj4.print_data();
    our_ptr->print();  // Bad data, they have free'd
    // double delete when our_ptr goes out of scope

    return 0;
}

Other questions I read related to this topic...

Aucun commentaire:

Enregistrer un commentaire