从函数返回动态创建的数组

时间:2010-03-20 20:31:45

标签: c++ gcc

我正在尝试创建一个动态分配数组的函数,设置元素的值,并返回数组的大小。数组变量是一个在函数外部声明并作为参数传递的指针。这是代码:

#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循环的第一次迭代!我做错了吗?

7 个答案:

答案 0 :(得分:2)

如果你想以这种方式分配内存:

int doArray(int*& arr)

否则指针只会在函数范围内更改。

答案 1 :(得分:1)

您需要为doArray添加额外的间接级别。如上所述,它正确地分配了数组,但它没有正确地将指针值传回给调用者。一旦你回来,malloc的指针就会丢失。

如果您编写了一个函数来获取float并更改该值,将更改后的值传递回调用者,则需要使用指针: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;  

}

请注意它现在如何取消引用*arr内的doArray,以及该调用现在如何写为doArray(&arr)

答案 2 :(得分:1)

您按值传递数组指针 ;这意味着当您的doArray函数返回时,arr中的main中的值仍为NULL - doArray内的分配不会更改它。

如果要更改arr(这是int *),则需要传入指针或对其的引用;因此,您的函数签名将包含(int *&arr)(int **arr)。如果您将其作为**传入,则还必须将函数内部的语法从使用arr更改为*arr(指针解除引用),并且您将其称为所以:doArray(&arr)

此外,在C ++中,您应该使用new int[sz]而不是malloc

答案 3 :(得分:0)

函数中的arr变量是main函数中arr指针的本地副本,原始版本未更新。您需要传递指针指针或指针引用(前者也可以在普通c中使用,后者仅在c ++中使用)。

int doArray(int **arr)

int doArray(int*& arr)

答案 4 :(得分:0)

将签名更改为(特定于c ++):

int doArray(int *&arr)

所以指针会在退出doArray时被更改。

答案 5 :(得分: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;  

}  

这应该有用。

答案 6 :(得分:0)

正如其他人所指出的那样,你是按值传递你的数组(int *),所以当你说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时,除了返回大小之外,还有更多的自我方式,因为您可以只询问arr.size(),如果您真的很喜欢,可以使用for_each或{{ 1}}打印所有元素。