2010-03-20 186 views
1

動態創建的數組我試圖創建一個動態分配數組,設置元素值並返回數組大小的函數。數組變量是一個在函數外聲明並作爲參數傳遞的指針。代碼如下:返回從函數

#include <cstdlib> 
#include <iostream> 
using namespace std; 

int doArray(int *arr) { 
    int sz = 10; 
    arr = (int*) malloc(sizeof(int) * sz); 

    for (int i=0; i<sz; i++) { 
     arr[i] = i * 5; 
    } 

    return sz; 
} 

int main(int argc, char *argv[]) { 

    int *arr = NULL; 
    int size = doArray(arr); 

    for (int i=0; i<size; i++) { 
     cout << arr[i] << endl; 
    } 

    return 0; 

} 

由於某些原因,程序在main()中for循環的第一次迭代終止!難道我做錯了什麼?

回答

1

你傳遞數組指針按值;這意味着,當你doArray函數返回,在mainarr值仍是NULL - 內doArray的分配不會改變它。

如果要更改值的arr(這是一個int *),則需要在任何一個指針或對它的引用通過;因此,你的函數簽名將包含兩種(int *&arr)(int **arr)。如果你把它當作一個**,你還必須在函數內部的語法使用arr*arr(指針解引用)改變,你會調用它像這樣:doArray(&arr)

同樣,在C++中你確實應該使用new int[sz],而不是malloc

2

如果你想分配內存的方式,你必須使用:

int doArray(int*& arr) 

否則指針將僅在函數範圍內改變。

0

你的函數中的arr變量是的副本arr指針在主函數中,並且原來沒有更新。你需要傳遞一個指向指針或指針的指針(前者也可以在純c中工作,後者只能在C++中工作)。

int doArray(int **arr) 

int doArray(int*& arr) 
1

你需要額外的間接級別添加到doArray。正如所寫,它正確地分配數組,但它不會正確地將指針值傳回給調用者。一旦你回來,malloc的指針會丟失。

如果您編寫了一個函數來獲取浮點值並更改值,將更改後的值傳遞給調用者,它需要一個指針:foo(float *f)。同樣,在這裏,您想要將int*的值傳遞給調用方,因此必須用第二個星號將您的函數聲明爲doArray(int **arr)

int doArray(int **arr) { 
    int sz = 10; 
    *arr = (int*) malloc(sizeof(int) * sz); 

    for (int i=0; i<sz; i++) { 
     (*arr)[i] = i * 5; 
    } 

    return sz; 
} 

int main(int argc, char *argv[]) { 

    int *arr = NULL; 
    int size = doArray(&arr); 

    for (int i=0; i<size; i++) { 
     cout << arr[i] << endl; 
    } 

    return 0; 

} 

注意它現在怎麼解引用*arrdoArray內,呼叫現在是如何寫成doArray(&arr)

0

更改簽名(特異於C++):

int doArray(int *&arr) 

所以指針將在出口處從doArray改變。

0

您需要一個指向doArray()參數中指針的指針。如果你以前從未使用過指針編程,這可能會讓人困惑。我發現如果用typedef充分註釋代碼,可以更容易地看到正確的類型。

你有正確的想法,(int *)可以用來表示一個數組。但是,如果你想改變在main()的變量ARR的價值,你需要一個指針,所以打電話時,你將最終(未測試的代碼)類似如下

typedef int *IntArray; 

int doArray(IntArray *arr) { 
    int sz = 10; 
    *arr = (IntArray) malloc(sizeof(int) * sz); 
    IntArray theArray = *arr; 

    for (int i=0; i<sz; i++) { 
     theArray[i] = i * 5; 
    } 

    return sz; 
} 

doArray,你需要通過你的變量的地址(這樣doArray知道在哪裏寫):

int main(int argc, char *argv[]) { 

    int *arr = NULL; 
    int size = doArray(&arr); 

    for (int i=0; i<size; i++) { 
     cout << arr[i] << endl; 
    } 

    return 0; 

} 

這應該工作。

0

正如其他人所指出的那樣,你是按值傳遞的數組(整型*),所以當你說arr=...你沒有真正改變你傳入數組。

你也得到了內存泄漏,就像你寫的那樣。這不是什麼大不了的事,當你只能在你的程序的身體打電話doArray一次,但如果它被一再呼籲和數組是從不free d(或delete d,如果用new使得它),那麼它可能會導致問題。通常,處理此問題的最佳方法是使用STL。然後你會寫

 
#include <vector> 
#include <iostream> 
int doArray(std::vector<int> &arr) { 
    int sz = 10; 
    arr.resize(sz); 
    for (int i=0; i<sz; i++) { 
     arr[i] = i * 5; 
    } 
    return sz; 
} 

int main(int argc, char *argv[]) { 
    std::vector<int> arr; 
    int size = doArray(arr); 
    for (int i=0; i<size; i++) { 
     std::cout << arr[i] << std::endl; 
    } 
    return 0; 
}

然而,隨着STL有更多idomatic方式比返回的大小,因爲你可以問arr.size(),如果你得到真正看中的,可以使用功能,如for_eachostream_iterator打印所有元素。