【发布时间】:2021-04-14 11:19:19
【问题描述】:
我正在使用一个库,为了构造我使用的某个对象,它需要一个指向对象的原始指针。我不确定它会对指针做什么,为了使我的代码尽可能安全,我应该将什么传递给这个函数?
- 使用唯一指针 - 如果他们决定删除指针,我将进行双重删除
- 跟踪原始指针 - 不好,因为我必须记住写删除,但它仍然可能是双重删除
- 使用自动持续时间并给他们一个指针
给他们一个参考- 如果他们调用 delete,他们的代码会出错 - 使用共享指针 - 与唯一指针相同的双重删除问题,但现在我的作用域不会伤害他们的指针
根据我的阅读,选项 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(&by_ref);&ref不是参考,它采用地址ref。 -
阅读他们的文档。如果他们说他们拥有指针的所有权,那么您知道您不需要删除它。如果他们什么都没说,那么通常假设您需要清理它。如果他们没有正确记录他们的内容,从而导致内存泄漏或双重删除,请大声向他们抱怨。
标签: c++ c++11 memory memory-leaks