我了解到有两种方法可以在C中声明一个数组:
int array[] = {1,2,3};
和
int* arr = malloc(3*sizeof(int));
为什么arr被称为自由指针?为什么我不能更改数组中包含的地址,而我可以使用数组?
答案 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]
。