我正在运行以下代码:
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("%i\n", *a);
printf("%i\n", *a);
return 0;
}
正如预期的那样,我在第一行得到 1,在第二行得到一些垃圾值(例如 6422260)。解释是什么?我希望两条线都得到 1。
最佳答案
如果是这样:
int out[size];
不会出现在文件范围中(换句话说,出现在函数内部),它定义了一个具有自动存储持续时间的变量。这意味着只要执行在其范围内(即最近的大括号组),变量就存在。一旦离开作用域,变量就消失了。
在 C 中不可能返回数组,return out
相反,返回一个指向数组第一个元素的指针。所以你看到了问题:指针指向一个不再存在的对象。
现在使用您的代码,第一次调用 printf()
似乎有效。这是“意外”(根本无法保证),但可以解释:在您的实现中,没有任何内容会更改数组所在所在的内存,直到另一个函数(此处为 printf()
)调用并用它自己的局部变量覆盖该内存。
如何正确执行此操作:有几种可能性:
- 让调用者提供数组。
- 使用
malloc()
返回一个指向已分配数组的指针如另一个答案所示,调用者必须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("%i\n", *a);
printf("%i\n", *a);
return 0;
}
关于c - 在这种情况下取消引用并打印指针 a 会做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45613541/