C ++从函数返回指向数组的指针的正确方法 [英] C++ correct way to return pointer to array from function

查看:231
本文介绍了C ++从函数返回指向数组的指针的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C ++相当陌生,并且一直避免使用指针。从我在线阅读我不能返回一个数组,但我可以返回一个指针。我做了一个小代码来测试它,并想知道这是否是正常/正确的方式来做到这一点:

  #include< ;&的iostream GT; 
使用namespace std;

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

int main(){
int arr [5] = {1,2,3,4,5};
int * pArr = test(arr); (int i = 0; i <5; i ++)cout cout<< endl;
返回0;
}






编辑:这似乎不好。如何重写它?

  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;
退出;
}






编辑(再次):谢谢,这里有很多有用的答案:)我最终以此作为函数:

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

以下称之为:

  int m1 [5] = {1,2,3,4,5}; 
int m2 [5] = {6,7,8,9,10};
int * m3 = test(m1,m2); (int i = 0; i< 5; i ++)cout <<< m3 [i] cout<< endl;
delete [] m3;


解决方案

很难弄清楚它是如何在真实世界中使用的。这就是说,从函数返回指针时请注意一些注意事项:


  • 当您使用语法<$ c $创建数组c> int arr [5]; ,它在堆栈中分配,并且是函数的局部。
  • C ++允许你返回一个指向这个数组的指针,但它是 未定义的行为 来使用该指针指向本地作用域之外的内存。阅读这个伟大的答案使用真实世界的比喻以获得清晰的理解,而不是我所能解释的。

  • 如果可以保证数组内存未被清除,则仍然可以在该范围外使用该数组。在你的情况下,当你将 arr 传递给 test()

  • <如果你想传递指向动态分配数组的指针而不用担心内存泄漏,你应该阅读 std :: unique_ptr / std :: shared_ptr<>


编辑 - 回答用例矩阵乘法



您有两种选择。天真的方式是使用 std :: unique_ptr / std :: shared_ptr<> 。 Modern C ++的方法是在 operator * 中重载一个 Matrix 类,你必须使用新的右值引用,如果你想避免复制乘法结果以将其从函数中取出。除了使用复制构造函数 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;





$ b如果你用 int * res =测试(a,b); ,然后稍后在代码中,您应该调用 delete [] res code> test()
函数。您现在看到问题是手动记录何时调用 delete 非常困难。因此,在答案中概述的如何处理它的方法。

I am fairly new to C++ and have been avoiding pointers. From what I've read online I cannot return an array but I can return a pointer to it. I made a small code to test it and was wondering if this was the normal / correct way to do this:

#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;
}


Edit: This seems to be no good. How should I rewrite it?

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;
}


Edit (again): Thank you, there are a lot of helpful answers here :) I ended up with this as the function:

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

and this to call it:

int m1[5] = {1, 2, 3, 4, 5};
int m2[5] = {6, 7, 8, 9, 10};
int* m3 = test(m1, m2);
for (int i = 0; i < 5; i++) cout<<m3[i]<<endl;
cout<<endl;
delete[] m3;

解决方案

Your code as it stands is correct but I am having a hard time figuring out how it could/would be used in a real world scenario. With that said, please be aware of a few caveats when returning pointers from functions:

  • When you create a array with syntax int arr[5];, its allocated on the stack and is local to the function.
  • C++ allows you to return a pointer to this array, but it is undefined behavior to use the memory pointed to by this pointer outside of its local scope. Read this great answer using a real world analogy to get a much clear understanding than what I could ever explain.
  • You can still use the array outside the scope if you can guarantee that memory of the array has not be purged. In your case this is true when you pass arr to test().
  • If you want to pass around pointers to a dynamically allocated array without worrying about memory leaks, you should do some reading on std::unique_ptr/std::shared_ptr<>.

Edit - to answer the use-case of matrix multiplication

You have two options. The naive way is to use std::unique_ptr/std::shared_ptr<>. The Modern C++ way is to have a Matrix class where you overload operator * and you absolutely must use the new rvalue references if you want to avoid copying the result of the multiplication to get it out of the function. In addition to having your copy constructor, operator = and destructor, you also need to have move constructor and move assignment operator. Go through the questions and answers of this search to gain more insight on how to achieve this.

Edit 2 - answer to appended question

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;
}

If you are using this as int *res = test(a,b);, then sometime later in your code, you should call delete []res to free the memory allocated in the test() function. You see now the problem is it is extremely hard to manually keep track of when to make the call to delete. Hence the approaches on how to deal with it where outlined in the answer.

这篇关于C ++从函数返回指向数组的指针的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆