c - 在这种情况下取​​消引用并打印指针 a 会做什么?

标签 c pointers dereference

我正在运行以下代码:

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() )调用并用它自己的局部变量覆盖该内存。

<小时/>

如何正确执行此操作:有几种可能性:

  1. 让调用者提供数组。
  2. 使用 malloc() 返回一个指向已分配数组的指针如另一个答案所示,调用者必须 free()它。
  3. 添加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/

相关文章:

c - 如何在 C 中动态分配、填充某些点并打印二维数组?

android - Android NDK 中的函数调用崩溃

c - 变量实例

C 字符串指针函数 strdel

C : Dereferencing pointer to incomplete type error

c - 将数组传递给函数时,是否需要提供元素数作为参数?

c - 在将数组的递增地址传递给函数时如何获得此输出?

c - 使指针指向数组的末尾

c - 引用/取消引用身份

svn - Subversion 客户端 (svn) 可以像文件一样取消引用符号链接(symbolic link)吗?