我正在运行以下代码:
int* range(int start, int end, int step){
int size = (end - start)/step;
int out[size];
for(int i = 0, j = start; i < size; i++, j += step){
out[i] = j;
}
return out;
}
int main()
{
int *a = range(1, 5, 1);
printf("%in", *a);
printf("%in", *a);
return 0;
}
正如预期的那样,我在第一行得到 1,在第二行得到一些垃圾值(例如6422260(。解释是什么?我希望在两条线上都得到 1。
如果这样:
int out[size];
不出现在文件范围内(换句话说,出现在函数内部(,它定义了一个具有自动存储持续时间的变量。这意味着只要执行在其作用域内(这是最接近的大括号集(,变量就存在。一旦范围离开,变量就消失了。
在 C 中不可能返回数组,return out
而是返回指向数组第一个元素的指针。所以你会看到问题:指针指向一个不再存在的对象。
现在有了你的代码,第一次调用printf()
似乎有效。这是"偶然的"(完全不能保证(,但可以解释:在您的实现中,不会更改数组所在的内存,直到调用另一个函数(此处printf()
(并用自己的局部变量覆盖此内存。
如何正确执行此操作:有几种可能性:
- 让调用方提供数组。
- 使用
malloc()
返回指向已分配数组的指针,如 Anoher Answer 所示,调用方必须free()
它。 - 向数组定义添加一个
static
,这会给它静态存储持续时间(在程序的整个执行时间内(,但要注意这样做的严重后果:这个数组永远只有一个实例,会产生各种各样的问题,所以,最好不要。
恕我直言,1. 是最惯用的 C方法,使用您的原始代码:
void range(int *out, int start, int end, int step){
int size = (end - start)/step;
for(int i = 0, j = start; i < size; i++, j += step){
out[i] = j;
}
}
int main()
{
int a[5];
range(a, 1, 5, 1);
printf("%in", *a);
printf("%in", *a);
return 0;
}