我正在尝试创建一个动态分配数组的函数,设置元素的值,并返回数组的大小。数组变量是一个在函数外部声明并作为参数传递的指针。这是代码:
#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循环的第一次迭代!我做错了吗?
答案 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}}打印所有元素。