【问题标题】:What to give a function that expects a raw pointer?给一个需要原始指针的函数提供什么?
【发布时间】:2021-04-14 11:19:19
【问题描述】:

我正在使用一个库,为了构造我使用的某个对象,它需要一个指向对象的原始指针。我不确定它会对指针做什么,为了使我的代码尽可能安全,我应该将什么传递给这个函数?

  1. 使用唯一指针 - 如果他们决定删除指针,我将进行双重删除
  2. 跟踪原始指针 - 不好,因为我必须记住写删除,但它仍然可能是双重删除
  3. 使用自动持续时间并给他们一个指针给他们一个参考 - 如果他们调用 delete,他们的代码会出错
  4. 使用共享指针 - 与唯一指针相同的双重删除问题,但现在我的作用域不会伤害他们的指针

根据我的阅读,选项 3 似乎是我应该做的 - 他们不应该在指针上调用 delete,这种格式强制执行。但是,如果我不知道他们现在或将来是否会在我给他们的参考资料上调用 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;
}

我读到的与此主题相关的其他问题...

【问题讨论】:

  • 为什么要猜?阅读该库的手册以了解它是否会删除指针。
  • “给他们一个参考 - 如果他们调用 delete,他们的代码会出错” - 不确定你的意思,如果函数需要一个指针,你不能通过一个参考。在BlackBox obj3 = BlackBox(&amp;by_ref); &amp;ref 不是参考,它采用地址 ref
  • 阅读他们的文档。如果他们说他们拥有指针的所有权,那么您知道您不需要删除它。如果他们什么都没说,那么通常假设您需要清理它。如果他们没有正确记录他们的内容,从而导致内存泄漏或双重删除,请大声向他们抱怨。

标签: c++ c++11 memory memory-leaks


【解决方案1】:

你无法用你所拥有的信息来解决这个问题。所有的选择都会产生垃圾。

您必须阅读您正在使用的 API 的文档。

在不知道他们是否拥有指针所有权的情况下执行 4 个答案中的任何一个都会导致问题。

生活有时很糟糕。

如果您有一个损坏的或恶意的 API,唯一安全的做法是在一个单独的进程中与之交互,小心地刷新所有通信,然后关闭该进程。

如果 API 没有损坏或恶意,您应该能够知道它是否正在获取指向对象的所有权。在不知道这一点的情况下调用 API 是新手 C++ 程序员的常见错误。不要这样做。是的,这很糟糕。

如果此 API 完全是内部的并且您有任何控制权,请设法将所有“拥有指针”参数设为 std::unique_ptr&lt;&gt;s。这在 API 中清楚表明您打算拥有该对象并稍后将其删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多