在这种情况下,取消引用和打印指针a会做什么?

时间:2017-08-10 12:18:21

标签: 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分。

1 个答案:

答案 0 :(得分:0)

如果:

int out[size];

不会出现在文件范围中(换句话说,出现在函数内),它定义了一个带有自动存储持续时间的变量。这意味着变量只有存在,只要执行在其范围内(这是最接近的括号集)。保留范围后,变量就消失了。

在C中返回数组是不可能的,return out会将指针返回到数组的第一个元素。所以你看到了问题:指针指向一个不再存在的对象。

现在使用您的代码,第一次调用printf() 似乎即可使用。这是偶然的&#34; (根本没有保证),但可以解释一下:在您的实现中,没有任何内容会改变数组 所在的内存,直到另一个函数(此处为printf())为止使用自己的局部变量调用并覆盖此内存。

如何正确地做到这一点:有几种可能性:

  1. 让调用者提供数组。
  2. 使用malloc()返回指向已分配数组的指针,如另一个回答所示,调用方必须free()
  3. 向数组定义添加static,为其提供静态存储持续时间(对于程序的整个执行时间),但请注意这种严重后果: #39;永远只有这个阵列的一个实例,造成各种各样的问题,所以,最好不要。
  4. 恕我直言,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;
    }