如何从函数返回动态分配的指针数组?

Posted

技术标签:

【中文标题】如何从函数返回动态分配的指针数组?【英文标题】:How do I return a dynamically allocated pointer array from a function? 【发布时间】:2012-02-16 15:32:56 【问题描述】:

我现在在课堂上开始动态内存分配,对它有一个很好的理解,但不能完全正确地使用它。我觉得我可能对指针也不太擅长:p

我的导师给出了创建一个名为 readArray 的函数的说明,该函数将提示用户输入一个数字作为大小,以动态创建一个该大小的整数数组。然后我将新数组分配给一个指针。然后我应该提示用户填充数组。然后我应该返回新创建的数组和大小。

我不知道如何返回数组,我认为在动态分配内存时应该在使用它后删除分配以防止泄漏。

必须将数组和大小返回给 main,以便我可以将其传递给其他函数,例如排序函数。

我将非常感谢我能得到的任何帮助,因为我的思考过程一直朝着错误的方向发展。

#include <iostream>
using namespace std;

int* readArray(int&);
void sortArray(int *, const int * );

int main ()

   int size = 0;
   int *arrPTR = readArray(size);
   const int *sizePTR = &size;
   sortArray(arrPTR, sizePTR);

   cout<<arrPTR[1]<<arrPTR[2]<<arrPTR[3]<<arrPTR[4];

        system("pause");
        return 0;



int* readArray(int &size)

   cout<<"Enter a number for size of array.\n";
   cin>>size;
   arrPTR = new int[size];

   for(int count = 0; count < (size-1); count++)
       
       cout<<"Enter positive numbers to completely fill the array.\n";
       cin>>*(arrPTR+count);
   

   return arrPTR;

【问题讨论】:

您的示例中的一个小错误是 readArray 的原型与您实现的不同。尽管没有必要,您也可以考虑在原型中提供变量名称以帮助记录它们的作用。 您通常不想更改示例代码以匹配解决方案。这就是答案的目的(当您进行这样的更新时,这可能没有意义)。 虽然 C++ 上的大多数类可能很早就涵盖了这样的原始数组,但我认为这是一个坏主意。应该教初学者使用向量,将原始数组和手动动态分配留到课程后面作为高级主题。这就是 Bjarne Stroustrup 出色的初学者书籍Programming—Principals and Practice Using C++ 的处理方式。 【参考方案1】:

如果您使用std::vector&lt;int&gt;,您将不需要这样做,这是非常好的选择。

使用它:

std::vector<int> readArray()

    int size = 0;
    cout<<"Enter a number for size of array.\n";
    cin >> size;
    std::vector<int> v(size);

    cout<<"Enter "<< size <<" positive numbers to completely fill the array : ";
    for(int i = 0; i < size; i++)
       
        cin>> v[i];
    
    return v;

【讨论】:

这将是完美的解决方案,但似乎他们现在应该研究 new 运算符的用法,提及向量(和其他容器)可能会令人困惑。恕我直言。 我还没有学过向量,并且赋值非常具体地使用指针和 new 运算符。 @Vyktor:C++11 编译器将通过移动向量来返回它;一个像样的 C++03 编译器会省略副本。 这是 C++ 课程应该的教学方式。尽管 C++ 上的大多数类可能很早就涵盖了这样的原始数组,但这是一个错误。应该教初学者使用向量,将原始数组和手动动态分配视为高级主题。 Bjarne Stroustrup 的初学者书籍Programming—Principals and Practice Using C++ 正确地做到了这一点。 @bames53:我不同意。在大学里,教授基础c++的目标不仅仅是“正确使用c++”。这些课程的目标之一也是让学生了解内存分配[自动/动态]、引用变量和值变量之间的区别、内存布局……理解这些概念通常需要一些关于动态数组分配的繁琐工作并使用指针[指向指针的指针...]【参考方案2】:

要返回一个数组:将readArray() 声明为int* readArray() [返回int* 而不是int],并返回arrPTR 而不是size。这样,您就返回了arrPTR 指向的动态分配的数组。

关于删除:当你使用完数组后,你确实应该删除它。在您的示例中,在您的 main() 函数中的 return 0 之前执行此操作。 请确保由于您使用new[] 分配了内存,您还应该使用delete[] 释放它,否则 - 您的程序将发生内存泄漏。

【讨论】:

确保使用delete []删除它 @Vyktor:这是作业,我只是给了他一些提示,如果我按照你的建议去做,他不会从中学习。 @Joe:你是 100% 正确的。对我们来说似乎微不足道的东西,不适合初学者。我将编辑我的答案并添加它。 @amit 我已经按照你说的做了,并在顶部编辑了我的代码,但我仍然遇到问题。在int *arrPTR = readArray(size); readArray 上出现错误“多个重载函数“readArray”实例与参数列表匹配。” 没关系,我在函数声明中忘记了引用变量:p【参考方案3】:

就像 amit 所说,您可能应该返回数组而不是大小。但是由于您仍然需要大小,因此将readArray 更改为:

///return array (must be deleted after)
///and pass size by reference so it can be changed by the function
int* readArray(int &size);

然后这样称呼它:

int size = 0;
int *arrPTR = readArray(size);
///....Do stuff here with arrPTR
delete arrPTR[];

更新后:

int* readArray(int size); ///input only! need the & in the declaration to match
                          ///the function body!

错了,因为你的实际定义是int &amp;size。 您也不要在readArray 中声明arrPTR,只需分配即可。

【讨论】:

以上是关于如何从函数返回动态分配的指针数组?的主要内容,如果未能解决你的问题,请参考以下文章

将数组动态分配到带有指针参数的函数中

怎么动态分配指针数组

C语言中的动态内存分配的用法举例

指针做参数的动态内存分配与二重指针(上)

如何复制动态分配的对象(具有一个类的 const 成员)

调整动态分配的指针数组的大小(复制构造函数不起作用?)