2010-03-20 188 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打印所有元素。