从函数返回动态分配的数组会导致内存泄漏吗?

Me *_*d I 5 c++

我问这个问题是为了减轻我对以下程序的困惑.我知道在某些上下文中使用数组会使数组衰减为指向其第一个元素的单个指针.我有一个函数,通过指针返回此数组(使用此函数创建new[]).数组是否会衰减,导致指针只指向第一个元素?这是一个例子:

int *foo() {
    int *t = new int[10];

    return t;
}

int main() {
    int *p = foo();
}
Run Code Online (Sandbox Code Playgroud)

这就是混乱的地方.我不知道是p指向第一个元素还是指向整个数组.所以我有以下问题:

  • 通过指针返回数组会导致它的衰减(并因此导致内存泄漏)?
  • 是否p指向数组的第一个元素?
  • 如果以上两个是真的,使用delete[]on p会导致未定义的行为吗?

我希望这些问题能得到解答,这样我才能完全理解这个程序.谢谢.

jua*_*nza 7

通过指针返回数组会导致它的衰减(并因此导致内存泄漏)吗?

你实际上是在返回t一个指针的副本.它已经指向动态分配的数组的第一个元素.如果你没有打电话delete [],只会有内存泄漏.

p指向数组的第一个元素吗?

如果上面两个是真的,在p上使用delete []会导致未定义的行为吗?

不,这样做很好.只要函数返回指向动态分配的数组的指针.

你已经发现了这个成语的严重问题:你不知道你是否得到一个指向元素的指针,一个指向动态分配数组的第一个元素的指针,一个指向全局的指针.你不能看你是否需要调用函数的返回类型知道delete,delete []或者不叫删除的.解决方案:不要返回指针!返回尤为明显表达发生了什么类型,而这需要管理自己的资源(照顾std::vector,std::array,std::unique_ptr,std::shared_ptr...).


lee*_*mes 6

你的函数分配内存并返回一个指向的指针,或者更技术上,返回你正确知道它的第一个元素.

之后内存会发生什么影响取决于调用者.这意味着当返回的数组不再使用时,调用者应该使用它删除它delete[].如果调用者不遵守此规则,则程序会泄漏内存.如果您编写类似的代码,您应该在方法的文档中强调这一点!

更现代的解决方案就是使用智能指针.智能指针本身就是保护底层指针的对象(不是指针的指针).根据我们在这里讨论的智能指针的类型,它将在调用者超出范围时自动删除(唯一保留所分配内存的所有权),或者当其他人不再使用它时(共享所有权) .

有关详细信息,请参阅此问题:智能指针和数组

现在,如果函数是像你的问题一样编写的,那么它返回一个原始指针而不是一个智能指针,你仍然可以通过之后包装数组来利用调用者中的智能指针的功能.

关于要删除的元素数量/内存量,这完全取决于实现delete[],因此您不必担心调用者中的元素数量.但是,您也无法查询要使用它们的元素数量.如果你需要元素的数量,你也必须返回它们,也许是通过"out参数".

在现代C++中,我强烈建议使用与原始数组不同的数据结构,std::vector例如,或者std::map如果需要关联容器,以及诸如"谁删除这个分配的内存?"之类的问题.消失了.