【问题标题】:How to tell if a function parameter can be safely deleted如何判断函数参数是否可以安全删除
【发布时间】:2019-01-16 20:14:37
【问题描述】:

我想知道是否有任何方法可以判断一个函数是否可以安全地删除作为参数传递的对象。

代码:

struct Test {

};

void f(Test *ptr) {
    delete ptr;   //if i delete the pointer here,
                  //i cannot use obj in main
}

int main() {
    Test *obj = new Test;

    f(new Test);
    f(obj);

    //delete obj;   //obj has already been deleted in f()
}

有没有办法释放 f(new Test) 分配的内存,但保留 obj 并在 main() 中仍然使用它?

【问题讨论】:

  • std::shared_ptr 或其他智能指针,视情况而定。但是,您标记了 c++98,所以我假设您没有使用现代 c++?通常在被调用者中传递指针并删除将被认为是不好的做法。人们宁愿期望 obj 在已分配的 main 中被释放。但实际上,应该避免原始分配,并且只有在绝对必要的情况下才能将其封装到类中;例如。在 Test 中进行(取消)分配,并确保在析构函数中或更早地释放所有内容。
  • 你不能。您需要通过规则建立ownership,并尽可能地执行这些规则。
  • 感谢您澄清原始指针的使用。确实这是 c++98(所以没有智能指针)。
  • @Alex "这是 c++98(所以没有智能指针)" - C++98 有 std::auto_ptr 智能指针。或者您可以使用来自Boost 库的智能指针。

标签: c++ c++98


【解决方案1】:

如果你可以迁移到 C++11,你应该使用std::shared_ptr,你的问题就解决了。 shared_ptr 将关注指针的用户数量,并在最后一个用户处理它时自动清理它。我强烈建议转移到现代 C++,它可以解决很多问题。

你也可以看看Boost SmartPtr——它本质上是一样的,可以在 C++11 之前使用。

您也可以尝试自己实现此类实用程序,但您必须确保正确实现它 - 参考计数器按照Rule of Three 的精神正确递增和递减


如果您必须使用原始指针,那么标准 C++ 中无法保证指针会(或不会)被函数释放。
通知其他程序员您的函数想要获取指针所有权(并将删除它)的唯一方法是通过 documentation,在代码中(使用 cmets)或使用单独的文档(如果例如,您创建一个 API)。

但是,您应该认真考虑函数是否应该获得指针的所有权。功能拥有它是否合理?如果没有,就留下它,让分配函数处理释放。

【讨论】:

    【解决方案2】:

    实际上你可以在 C++ 98 中做到这一点。不需要新的标准。 您不要将删除放在 f 中。相反,只需使用 auto_ptr 保护创建您传递给 f 的对象:

    Test *obj = new Test();
    
    f(auto_ptr<Test>(new Test()).get());
    f(obj);
    

    自动指针会确保在函数执行结束后释放对象。

    嗯,老实说,它*几乎是一样的。如果您明确需要删除 f 内的指针,而不仅仅是保护它以确保它被释放,那么您确实需要智能指针而不仅仅是 auto_ptr,为此您必须使用 boost 或 c++11 或只编写它自己,实现起来真的不复杂。

    还要注意 auto_ptr 在新标准中已被弃用,因此此代码不向前兼容。

    【讨论】:

    • 谢谢,我不知道 auto_ptr 在 c++98 中是如何工作的。它是用于现代 c++ 中的其他东西,还是只是被弃用而不被使用?
    • @AlexGh 从 C++11 开始不推荐使用,并在 C++17 中完全删除。 std::auto_ptr 使用起来有点奇怪,例如不能在标准容器中使用。你也不能用它来存储数组。
    猜你喜欢
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2013-03-30
    • 2011-05-19
    • 1970-01-01
    相关资源
    最近更新 更多