【问题标题】:C++ freeing heap-allocated variables in functionsC++ 在函数中释放堆分配的变量
【发布时间】:2021-09-27 08:37:22
【问题描述】:

这是函数的一部分:

std::queue<std::string>* shunting_yard(std::vector<std::string> input){
    std::queue<std::string>* output = new std::queue<std::string>();
    ...
    return output;

我已经动态分配队列output 指向堆上。但是,当我尝试释放/删除 int main() 中的队列时,我收到一个错误,因为 output 被声明超出范围。

考虑到我在上面的函数中返回output - 所以我不能在函数内部释放它 - 我怎样才能确保没有内存泄漏?我想到的一种可能的解决方案是在全局范围内声明std::queue&lt;std::string&gt;* output,在函数内声明output = new std::queue&lt;std::string&gt;(),但是对于这个超出范围的错误还有其他解决方案吗?

【问题讨论】:

  • std::unique_ptr。但实际上没有理由动态分配std::queue,因为它的存储本身又是动态分配的。只需返回值。
  • @Quentin 我决定返回一个指向它的指针,因为我想检查它是否是一个 NULL 指针(以防函数内部出现任何问题)。这是一个正当的理由吗?
  • 没有。如果出现问题并且函数无法返回合理的结果,则抛出异常。
  • 如果异常没有意义(如未能产生好的结果不是异常事件),请使用std::optional。您还可以返回 std::pair 中的 std::queuebool。如果结果可以接受,请将bool 设置为true

标签: c++ memory memory-management scope


【解决方案1】:

您不会删除变量或指针。你删除了你用new分配的东西。行:

std::queue<std::string>* output = new std::queue<std::string>();

不使用new 分配名为output 的变量。它分配一个没有名字的队列,并创建一个名为output的局部变量,并将队列的地址存储到局部变量output中。

这一行:

return output;

返回队列的地址。因为它也结束了函数,所以局部变量output被销毁(就像所有局部变量一样)。调用者收到地址。

你如何调用这个函数?您没有显示该代码,但它类似于:

std::queue<std::string>* woof = shunting_yard(meow);

在这种情况下,这会在调用者中创建一个名为 woof 的新局部变量,该变量现在保存 shunting_yard 创建的队列的地址。

您可以通过将队列地址传递给delete 来删除队列。它的地址存储在变量woof 中。所以你可以写delete woof;。只要地址相同,地址存储在不同变量中的事实是无关紧要的。


更高级的程序员将使用std::unique_ptr&lt;std::queue&lt;std::string&gt;&gt;。但我建议在学习unique_ptr 之前首先手动学习newdelete,以便您了解unique_ptr 的实际作用。

真正高级的程序员会意识到他们根本不使用new,而只是使用std::queue&lt;std::string&gt;(没有指针)。

【讨论】:

    猜你喜欢
    • 2013-02-28
    • 2017-12-02
    • 2020-12-13
    • 2012-11-06
    • 2018-07-29
    • 2012-06-28
    • 1970-01-01
    • 2019-04-15
    • 2018-06-23
    相关资源
    最近更新 更多