0

有没有办法将数组作为 c++ 中的函数的结果返回?

int* returnArray()
{
    int* arr = new int[3];
    return arr;  
}

这种方式 arr 是一个局部变量,并且在函数返回后分配的内存块会丢失。除了在功能块之外定义一个数组之外,还有什么办法吗?

4

5 回答 5

2

分配的内存块不会丢失,因为内存是在堆上分配的。指向该内存的指针被复制,并正确返回给调用者。换句话说,您的代码没有任何问题 - 可能除了调用者必须知道数组大小才能对返回的数组做任何有用的事情。

您可能指的反模式如下所示:

// WRONG: returns pointer to local data
int* returnArray() {
   int arr[3] = {1, 2, 3};
   return arr;
}

这是一个错误,因为arr它是在堆栈上分配的,并且函数返回指向该数据的指针。要修复它,需要将函数声明为返回数组,但 C++ 不允许这样做,因此必须间接完成。固定功能将如下所示:

struct Array {
    int array[3];
};

// correct: generated copy constructor correctly copies arr
Array returnArray() {
    Array arr = {{1, 2, 3}};
    return arr;
}

在生产代码中,如果您可以使用 C++11,您的函数将简单地返回std::array<int, 3>. C 风格的数组几乎总是在低级代码中用于实现容器,并且几乎不需要直接从函数中返回它们。

于 2013-11-13T12:46:00.953 回答
2

你返回一个指向数组的指针没关系,但问题是“谁负责删除它”,你可以使用智能指针:

std::unique_ptr<int[]> returnArray()
{
    std::unique_ptr<int[]> arr (new int[3]);
    return arr;  
}

每个人都很高兴。此外,您可以使用std::vector.

std::vector<int> returnArray()
{
    std::vector<int> arr(3);
    return arr;  
}
于 2013-11-13T12:46:17.643 回答
1

你有什么作品;问题是你让调用者负责记住删除动态数组。这是内存泄漏的好方法。

也许您正在考虑尝试返回本地数组:

int * returnArray() {
    int arr[3];
    return arr;   // BOOM! dangling pointer
}

这是错误的,因为该数组在函数返回时被销毁;之后使用指针将给出未定义的行为。

要解决这两个问题,请返回托管动态数组:

std::vector<int> returnVector() {
    std::vector<int> v(3);
    return v;
}
于 2013-11-13T12:57:48.730 回答
1

你的功能没问题。new在使用表达式之前,永远不会释放使用表达式获得的内存delete

这是函数返回时会丢失内存的版本:

// WRONG:
int* returnArray()
{
    int arr[3];
    return arr;
}

更好的方法是返回一个std::vector<int>.

于 2013-11-13T12:46:43.620 回答
0

实际上,您的代码很好但很危险,我的意思是,arr在您调用delete[]它之前,为剩余分配内存,这意味着您可以安全地访问数组的元素,但是使用这种方法将内存清理委派给源代码是一种不好的做法,并且会,最有可能导致内存泄漏或损坏。

我建议将数组作为参数传递,以便调用代码负责内存管理:

void returnArray(int* arr)
{
    ... Your code here managing array's contents ...
}

或者,如果这是一个类的方法,则从此类内部管理此内存。

编辑:或者更好的是,使用@M M 建议的智能指针。

于 2013-11-13T12:57:06.823 回答