简体   繁体   English

数组作为函数的返回值

[英]Array as return value of a function

Is there a way to return an array as a result of a function in c++? 有没有一种方法可以将返回的数组作为c ++中函数的结果?

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

This way arr is a local variable and the alocated memory block is lost after the function returns. 这样,arr是一个局部变量,并且在函数返回后丢失了分配的内存块。 Is there any way around this besides defining an array outside the function block? 除了在功能块外定义数组之外,还有其他方法吗?

Allocated memory block is not lost, since the memory is allocated on the heap. 由于内存是在堆上分配的,因此分配的内存块不会丢失。 The pointer to this memory is copied, and correctly returned to the caller. 指向该内存的指针被复制,并正确返回给调用者。 In other words, there is nothing wrong with your code - except possibly for the fact that the caller must know the array size in order to do anything useful with the returned array. 换句话说,您的代码没有任何问题-可能是调用者必须知道数组大小才能对返回的数组做任何有用的事情。

The anti-pattern you are probably referring to looks like this: 您可能要参考的反模式如下所示:

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

This is an error because arr is allocated on the stack, and the function returns a pointer to that data. 这是一个错误,因为在堆栈上分配了arr ,并且该函数返回了指向该数据的指针。 To fix it, one would need to declare the function as returning an array, but C++ doesn't allow this, so it must be done indirectly. 要修复它,需要将函数声明为返回数组,但是C ++不允许这样做,因此必须间接完成。 Fixed function would then look like this: 固定功能将如下所示:

struct Array {
    int array[3];
};

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

In production code, and if you can use C++11, your function would simply return std::array<int, 3> . 在生产代码中,如果可以使用C ++ 11,则函数将只返回std::array<int, 3> C-style arrays are almost always used in low-level code to implement containers and there is almost never a need to directly return them from functions. C样式数组几乎总是用在低级代码中以实现容器,并且几乎不需要直接从函数中返回它们。

You're returning a pointer to an array it's OK, but the problem is "who is responsible to delete it", you can use smart pointers: 您正在返回指向数组的指针是可以的,但是问题是“谁负责删除它”,可以使用智能指针:

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

And everyone is happy. 每个人都很高兴。 Also, you can use std::vector . 另外,您可以使用std::vector

std::vector<int> returnArray()
{
    std::vector<int> arr(3);
    return arr;  
}

Your function is okay as is. 您的功能还可以。 Memory obtained with a new expression is never deallocated until you use a delete expression. 使用new表达式获得的内存永远不会释放,直到您使用delete表达式。

This is the version that would lose the memory when the function returns: 该版本将在函数返回时丢失内存:

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

The even better way would be to return a std::vector<int> . 更好的方法是返回std::vector<int>

What you have works; 你所拥有的作品; the issue is that you've made the caller responsible for remembering to delete the dynamic array. 问题是您已经让调用者负责记住删除动态数组。 This is a good recipe for a memory leak. 这是内存泄漏的好方法。

Perhaps you were thinking of trying to return a local array: 也许您正在考虑尝试返回本地数组:

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

This is wrong, since this array is destroyed when the function returns; 这是错误的,因为该数组在函数返回时被销毁。 using the pointer after that will give undefined behaviour. 之后使用指针将产生不确定的行为。

To solve both issues, return a managed dynamic array: 要解决这两个问题,请返回托管动态数组:

std::vector<int> returnVector() {
    std::vector<int> v(3);
    return v;
}

Actually, you're code is fine but dangerous, I mean, allocated memory for arr remains until you call delete[] on it, meaning that you can safely access array's elements but delegating memory clean up to source code using this method is a bad practice and will, most probably, lead to a memory leak or corruption. 实际上,您的代码很好,但是很危险,我的意思是,为arr分配的内存将一直保留到您对它调用delete[]为止,这意味着您可以安全地访问数组的元素,但是使用此方法将内存清理工作委托给源代码是很糟糕的练习,很可能会导致内存泄漏或损坏。

I would recommend passing the array as a parameter so calling code is in charge of memory management: 我建议将数组作为参数传递,以便调用代码负责内存管理:

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

Or, if this is one class' method, manage this memory from inside this class. 或者,如果这是一个类的方法,请从此类内部管理此内存。

Edit: Or better, use smart pointers as suggested by @M M. 编辑:或者更好,使用@M M建议的智能指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM