C++ 从函数返回动态分配的数组是否会导致内存泄漏?

C++ 从函数返回动态分配的数组是否会导致内存泄漏?,c++,C++,我问这个问题是为了消除我对以下节目的困惑。我知道在某些上下文中使用数组会使数组衰减为指向其第一个元素的单个指针。我有一个通过指针返回这个数组的函数(这个函数是使用new[]创建的)。数组是否会衰减,导致指针只指向第一个元素?以下是一个例子: int *foo() { int *t = new int[10]; return t; } int main() { int *p = foo(); } 这就是困惑所在。我不知道p是指向第一个元素还是指向整个数组。因此,我有以

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

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

    return t;
}

int main() {
    int *p = foo();
}
这就是困惑所在。我不知道
p
是指向第一个元素还是指向整个数组。因此,我有以下问题:

  • 通过指针返回数组是否会导致数组衰退(并最终导致内存泄漏)
  • p
    是否指向数组的第一个元素
  • 如果上述两种情况属实,在
    p
    上使用
    delete[]
    是否会导致未定义的行为
我希望这些问题能得到回答,这样我就能完全理解这个项目。多谢各位

通过指针返回数组是否会导致数组的衰减(从而导致内存泄漏)

实际上,您返回的是
t
的一个副本,它是一个指针。它已经指向动态分配数组的第一个元素。只有在调用
delete[]
失败时,才会出现内存泄漏

p是否指向数组的第一个元素

如果以上两个都是真的,那么在p上使用delete[]是否会导致未定义的行为

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


您已经发现了这个习惯用法的一个严重问题:您无法知道是否获得了指向元素的指针、指向动态分配数组的第一个元素的指针、指向全局数组的指针。通过查看函数的返回类型,您无法知道是否需要调用
delete
delete[]
,或者根本不调用delete。解决方案:不要返回指针!返回一个类型,它表示正在发生的事情,并负责管理自己的资源(
std::vector
std::array
std::unique\u ptr
std::shared\u ptr
)。

您的函数分配内存并返回指向它的指针,或者更严格地说,到您正确知道的第一个元素

之后内存的情况由调用方决定。这意味着当返回的数组不再使用时,调用者应使用
delete[]
将其删除。如果调用方不遵守此规则,则程序会泄漏内存。如果您编写这样的代码,您应该在方法的文档中强调这一点

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

有关详细信息,请参见此问题:

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

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

<现代> C++中,<>强>强烈推荐使用不同于原始数组的数据结构< /强>,如<代码> STD::vector < /代码>,或<代码> STD::MAP< /COD>如果需要关联容器,那么“谁删除这个分配的内存”之类的问题就不存在了。 如果以上两种情况相同,那么在p上使用delete[]是否会导致未定义的行为 是吗

否,不删除[]p将导致内存泄漏

但是,delete[]神奇地知道数组的长度,而sizeof(p)不知道,
因为分配器跟踪分配的空间。但是,sizeof是在compiletime生成的固定值

如果下一行是
p='
或其他内容,则会“丢失”从foo返回的指针,然后砰的一声。。。内存泄漏。如果您忽略清理分配的内存,这只是内存泄漏。部分原因可能是“忘记”或“丢失”指向该内存的指针。“衰退”对使用动态存储时间创建的对象没有任何作用。它只是描述数组表达式发生的一些情况,将它们视为指针类型。内存泄漏不是关于如何在应用程序中传递指针,而是关于如何确保(“管理它”)所有已分配的内存也被释放。内存管理越简单,代码中出现内存泄漏的可能性就越小~>所以请尽可能多地遵循:)衰减只影响数组类型的变量。你没有这种东西。