簡體   English   中英

C ++如何從函數返回動態分配的數組

[英]C++ How to return dynamically allocated array from function

我剛開始學習C ++。 我正在閱讀互聯網上的禮儀,現在我在功能上創建了一個動態分配的數組。

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

    int * Array = new int[size];


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

如何將此函數返回到main()

好吧,返回大小和指針是明智的,因為否則將無法安全地使用生成的數組。

所以我們正在尋找一種從函數中返回兩個值的方法。 這可以通過獲取參考參數來完成,您可以通過參數參數指定其中一個值:

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

簡單,防漏和異常安全(理想情況下,您也可以清理用戶輸入)。

在大多數情況下,在C ++中,我們不需要使用operator new手動分配資源。

我建議改用std::vector<int> 與動態分配的普通數組相比,它具有以下優點:

  • 當示波器退出時,它將自動釋放保留的內存(您不必調用delete )。
  • 它有一個size()方法,因此您始終可以知道向量中包含多少元素。 將其與動態普通數組進行比較,您必須將該大小存儲在另一個變量中。
  • 您可以在構造后動態更改“數組”的resize()例如,使用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;
}

要使用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';
    }
}

在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>當然更好,但這似乎不是練習的重點。

使用的參考: 在函數中返回數組

您可以返回動態分配的數組,返回其指針:

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

但是,請注意,在他的方式中,您丟失了數組大小的重要信息(這對於使用數組的代碼非常重要,以避免緩沖區溢出)。

在現代C ++中,更好的方法是返回標准庫容器,如std::vector ,而不是原始指針。

請注意, std::vector實例確實知道它們的大小,並自動釋放它們的內存(相反,當你擁有原始擁有指針時,你必須顯式地調用delete[] )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM