C++从函数返回指向数组的指针的正确方法

asi*_*mes 23 c++ arrays pointers function

我对C++很新,一直在避免使用指针.从我在网上看到的,我不能返回一个数组,但我可以返回一个指向它的指针.我做了一个小代码来测试它,并想知道这是否是正常/正确的方法:

#include <iostream>
using namespace std;

int* test (int in[5]) {
    int* out = in;
    return out;
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int* pArr = test(arr);
    for (int i = 0; i < 5; i++) cout<<pArr[i]<<endl;
    cout<<endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编辑:这似乎并不好.我该怎么改写呢?

int* test (int a[5], int b[5]) {
    int c[5];
    for (int i = 0; i < 5; i++) c[i] = a[i]+b[i];
    int* out = c;
    return out;
}
Run Code Online (Sandbox Code Playgroud)

vvn*_*man 16

你现在的代码是正确的,但我很难弄清楚它是如何在现实世界中使用的.有了这个,请注意从函数返回指针时的一些注意事项:

  • 使用语法创建数组时int arr[5];,它在堆栈上分配并且是函数的本地数组.
  • C++允许您返回指向此数组的指针,但是使用此指针在其本地范围之外指向的内存是未定义的行为.使用真实世界的比喻阅读这个伟大的答案,以获得比我能解释的更清晰的理解.
  • 如果可以保证不清除阵列的内存,仍然可以在范围外使用该数组.在你的情况下,当你传递arr给你时,这是真的test().
  • 如果你想将指针传递给一个动态分配的数组而不用担心内存泄漏,你应该在std::unique_ptr/ 上做一些阅读std::shared_ptr<>.

编辑 - 回答矩阵乘法的用例

你有两个选择.天真的方式是使用std::unique_ptr/ std::shared_ptr<>.Modern C++方法是有一个Matrix你重载的类,你operator *绝对必须使用new,rvalue references如果你想避免复制乘法的结果以使它脱离函数.除了有你的copy constructor,operator =并且destructor,你还需要有move constructormove assignment operator.仔细阅读此搜索的问题和答案,以获得有关如何实现此目标的更多信息.

编辑2 - 回答附加的问题

int* test (int a[5], int b[5]) {
    int *c = new int[5];
    for (int i = 0; i < 5; i++) c[i] = a[i]+b[i];
    return c;
}
Run Code Online (Sandbox Code Playgroud)

如果您正在使用它int *res = test(a,b);,那么稍后在代码中,您应该调用delete []res以释放test()函数中分配的内存.你现在看到问题是手动跟踪何时进行呼叫是非常困难的delete.因此,在答案中概述了如何处理它的方法.


Nik*_* C. 9

你的代码没问题.请注意,如果返回指向数组的指针,并且该数组超出范围,则不应再使用该指针.例:

int* test (void)
{
    int out[5];
    return out;
}
Run Code Online (Sandbox Code Playgroud)

以上将永远不会起作用,因为outtest()返回时不再存在.不能再使用返回的指针.如果你做的使用它,你会读/写内存,你不应该.

在原始代码中,返回arr时数组超出范围main().显然这没问题,因为返回main()也意味着你的程序正在终止.

如果你想要的东西会一直存在并且不能超出范围,你应该分配它new:

int* test (void)
{
    int* out = new int[5];
    return out;
}
Run Code Online (Sandbox Code Playgroud)

返回的指针始终有效.请记住,在完成后再次删除它,使用delete[]:

int* array = test();
// ...
// Done with the array.
delete[] array;
Run Code Online (Sandbox Code Playgroud)

删除它是回收它使用的内存的唯一方法.

  • 更糟糕的是 - 有时它会起作用,取决于其他正在运行的内容、运行时间和月相 (2认同)