C ++如何从函数返回动态分配的数组

时间:2017-06-10 21:57:34

标签: c++

我刚开始学习C ++。我正在阅读互联网上的礼仪,现在我在功能上创建了一个动态分配的数组。

void array_() {
    int size;
    cin >> size;

    int * Array = new int[size];


    for (int i = 0; i < size; ++i)
        cin >> Array[i];
}

如何将此函数返回到main()

4 个答案:

答案 0 :(得分:7)

嗯,返回大小和指针是明智的,因为否则就无法安全地使用生成的数组。

所以我们正在寻找一种从函数中返回两个值的方法。这可以通过获取参考参数来完成,您可以通过参数指定其中一个值:

int *array_(int &size) {
    std::cin >> size;

    int *Array = new int[size];

    for (int i = 0; i < size; ++i)
        std::cin >> Array[i];

    return Array;
}

int main() {
    int size;
    int *arr = array_(size);
    // ...
    delete[] arr; // Don't forget to delete[] what has been new[]'d!
}

或者,您可以返回包含两个值的std::pair

std::pair<int *, int> array_() {
    int size;
    std::cin >> size;

    int * Array = new int[size];

    for (int i = 0; i < size; ++i)
        std::cin >> Array[i];

    return {Array, size};
}

int main() {
    auto arr = array_(size);
    // ...
    delete[] arr.second; // Don't forget still!
}

但这两个都是疯狂的坏主意,所以你现在可以开始编写实际的 C ++,这样它就不会像使用标准容器一样变形C:

std::vector<int> array_() {
    int size = 0;
    std::cin >> size;

    std::vector<int> vec(size);

    for(int &i : vec)
        std::cin >> i;

    return vec;
}

int main() {
    auto arr = array_(size);
    // ...
    // Now you can forget delete: no raw owning pointer, no worries.
}

简单,防漏和异常安全(理想情况下,您也可以清理用户输入)。

答案 1 :(得分:4)

在大多数情况下,在C ++中,我们不需要使用operator new手动分配资源。

我建议改用std::vector<int>。与动态分配的普通数组相比,它具有以下优点:

  • 当示波器退出时,它将自动释放保留的内存(您不必调用delete)。
  • 它有size()方法,因此您始终可以知道向量中包含的元素数量。将其与动态普通数组进行比较,您必须将该大小存储在另一个变量中。
  • 您可以更改&#34;数组的大小&#34;构造后动态(例如使用resize()方法)。

实施例

std::vector<int> array_() 
{
    int size;
    cin >> size;

    // Create a dynamic "array" with the given size.
    std::vector<int> result( size );

    for (int i = 0; i < size; ++i)
        cin >> result[i];

    return result;
}

使用&#34;数组&#34;来自main()

int main()
{
    // Call function array_() and store the result in variable v.
    std::vector<int> v = array_();

    // Print all elements of v using range-based loop.
    for( int x : v )
    {
        std::cout << x << '\n';
    }

    // Alternatively print all elements using classic loop with index.
    for( int i = 0; i < v.size(); ++i )
    {
        std::cout << v[i] << '\n';
    }
}

答案 2 :(得分:3)

在C ++中,您不能从“按原样”的函数返回数组类型的变量(即int arr[]),尽管您可以返回引用或指针一个数组。这是一些相当笨拙的语法。在显示的代码中,没有数组,而是指向一块动态分配的内存的指针。然而,主要的问题是,由于内存是动态分配的,当你返回一个指向该内存的指针时,你只给客户端一半的信息:数组的大小仍然未知。

因此,如果你真的想坚持动态分配的传统数组,你可以将数组的大小作为参考参数(“out-value”)传递给像这样的函数:

int* func(std::size_t& size_out) {
    // int n = ...;
    int* array = new int[n];
    size_out = n;
    return array;
}

int main() {
    int size;
    int* result = func(size);
    delete[] result;
    result = nullptr;
}

正如您所看到的,手动分配内存的副作用是客户端负责它,并且您必须在分配它的函数之外手动删除

但“超值”真的是一种糟糕的风格,特别是在API中。尽可能避免使用它们!

当然最好使用适当的动态数组工具,例如std::vector<T>,但这似乎不是练习的重点。

使用的参考:Return array in a function

答案 3 :(得分:0)

您可以返回动态分配的数组,返回其指针:

int* ProduceArray() {
    ...
    int* arrayPtr = new int[size];
    ...
    return arrayPtr;
}

但是,请注意,在他的方式中,您丢失了数组的 size 的重要信息(这对于使用该数组的代码非常重要,以避免缓冲区溢出)。

在现代C ++中,更好的方法是返回标准库容器,如std::vector,而不是原始指针。

请注意,std::vector个实例确实知道它们的大小,并自动释放它们的内存(相反,当你拥有原始拥有指针时,必须显式调用delete[]。)