如何表明需要删除返回值?

时间:2013-01-24 03:15:22

标签: c++ memory-management

我通常不是C ++开发人员。我通常的语言都是垃圾收集,他们为我工作,但C ++让我感兴趣。

我有一两个关于返回动态分配的对象或结构的问题。我的理解是它们必须动态分配,因此数据在堆中而不是堆栈中。如果我错了,请纠正我。

返回指针的最佳做法是什么?假设我正在编写一个库,如何在代码中指示是否应该删除返回的指针?如果我返回一个数组,我该如何返回数组的大小?

这些不是我在C#或javascript中必须面对的问题。这些问题都有两个方面:如果我使用其他人的库,我该寻找什么?

2 个答案:

答案 0 :(得分:5)

C ++有一个叫做RAII的习语。对您来说意味着您不必担心清理,并且资源将在代码中的已定义点释放。

例如,在函数中创建一个数组并返回它。这是一个没有RAII的典型实现(另一个是调用者分配内存并将其传入):

int *makeIntArray(std::size_t length) {
    return new int[length];
}

现在调用者需要记住释放这个内存。将其与RAII版本进行比较:

std::vector<int> makeIntArray(std::size_t length) {
    return std::vector<int>(length);
}

当向量超出范围时,从此返回的内容将释放其内存,这取决于调用者。它还提供了size()成员函数来获取元素的数量。

也就是说,最好在可能的情况下保持动态分配。如果您需要返回一个结构,比如说Str,只需按值返回:

Str makeStr() {
    return Str();
}

没有动态分配意味着没有额外的工作,无论是释放内存,还是将其包装成某种东西(在这种情况下是智能指针,如std::unique_ptr)。

对于其他库,您需要阅读文档以确保您必须拥有它返回的内容。如果必须,您可以做的一件事就是从中制作出一个RAII对象。例如:

int *makeSomeInt(int value) {
    return new int(value);
}

...

std::unique_ptr<int> myInt(makeSomeInt(5));
//memory freed when myInt goes out of scope

答案 1 :(得分:0)

我看到克里斯已经提供了一个很好的答案。添加的东西很少:

  • 远离 代码中的动态内存分配。让动态内存分配(和解除分配)尽可能由库完成。 (参见上面vector的示例。)

  • 如果您必须自己进行动态内存分配,那么每个内存(即指针)都必须拥有所有者。应该构建和破坏内存的是所有者,其他人只能使用

  • 如果您使用的是C ++ 11,那么请熟悉unique_ptr,这是您最常需要的。

    来自Dr.Dobb s:

      

    C ++ 11中有很多很棒的功能,但unique_ptr很突出   在代码卫生领域。简单地说,这是一个神奇的子弹   动态创建的对象。