什么是C中的自由指针?

时间:2017-07-19 14:04:10

标签: c arrays pointers

我了解到有两种方法可以在C中声​​明一个数组:

int array[] = {1,2,3};

int* arr = malloc(3*sizeof(int));

为什么arr被称为自由指针?为什么我不能更改数组中包含的地址,而我可以使用数组?

2 个答案:

答案 0 :(得分:5)

正如评论中所说,你从错误的来源学到了不正确的东西。

在第二种情况下,arr不是数组,它是指针。一个指针(如果分配成功)恰好包含一个可以容纳三个int的内存块的地址,但那不是一个数组。

这种混乱可能来自于数组"衰变"在某些情况下使用指针,但这并不能使它们等效。

答案 1 :(得分:1)

让我们看看这两个对象是如何在内存中布局的:

       +---+
array: | 1 | array[0]
       +---+
       | 2 | array[1]
       +---+
       | 3 | array[2]
       +---+

       +---+            +---+
  arr: |   | ---------> | ? | arr[0]
       +---+            +---+
                        | ? | arr[1]
                        +---+
                        | ? | arr[2]
                        +---+

所以,一个直接的区别 - 没有array对象与数组元素本身分开,而arr 与数组元素分开的对象。就C而言,只有array实际数组 - arr只是指向单个对象的指针,可能是第一个一系列对象的元素与否。

这就是为什么您可以将新地址值分配给arr,而不是array - 在第二种情况下,没有任何内容可以将新地址值分配给 。这就像尝试更改标量变量的地址 - 你不能这样做,因为操作没有任何意义。

这也意味着array[0]的地址与array的地址相同。 表达式 &array[0]array&array都会产生相同的地址值,但表达式的类型会有所不同(int * ,分别为int *int (*)[3]。相比之下,arr的地址arr[0]的地址相同;表达式arr&arr[0]将产生相同的值,但&arr不会,而且其类型将为int **而不是int (*)[3]