以下是一段代码示例:
int *a = malloc(sizeof(int) * n);
这段代码能够用来定义一个包含 n 个整数的数组吗?
int *a = malloc(sizeof(int) * n);
int arr[10];
定义了一个命名的数组对象。而你的指针声明和初始化并没有。
然而,malloc
调用(如果成功,并返回非 null
结果,且 n > 0
)将在运行时创建一个匿名的数组对象。
但它并没有 "定义一个数组 a
"。 a
是一个指针对象的名称。鉴于 malloc
调用成功,a
将指向一个数组对象的初始元素,但它本身不是一个数组。
请注意,由于该数组对象是匿名的,因此无法应用 sizeof
,也无法从指针中检索数组对象的大小。如果您需要知道数组的大小,您需要自己跟踪。
(一些评论认为 malloc
调用分配了可以容纳 n
个整数对象的内存,但并没有分配数组。如果是这样,那么你将无法访问创建的数组对象的元素。请参见 N1570 6.5.6p8 中指针加法的定义,以及 7.22.3p1 中关于 malloc
如何创建可访问数组的描述。)
a
不是数组的情况下出现 i == 0
的情况;如果 a
指向不是数组的对象,则 a[0]
是有效的。 - davmacmalloc
返回的指针如何用于访问数组的描述的引用。 - Keith Thompsona[i]
,其中(i >= 0 && i < n)
,只有在指针a
指向数组对象的元素时才有效”,但正如我所指出的那样,这是不正确的。 - davmacint *a = malloc(sizeof(int) * n);
malloc()
调用成功,你可以使用指针a
来像数组一样使用数组符号(例如a[0] = 5;
)。但是a
本身不是数组;它只是指向一个int
的指针(并且它可能是一个能够存储多个int
的内存块)。表明这可能是你主要关心的问题。但是我可以在我的程序中使用一个没有声明的数组a
p[i] == *(p + i) == *(i + p) == i[p]
i
或 p
中有一个是指针类型(p
也可以是数组,因为它在任何表达式中都会被转换为指针),因此,您就可以像访问数组一样对 a
进行索引。但是,a
实际上是一个指针。malloc()
所做的事情。
重要的区别在于:int array[10];
将array
声明为一个数组对象,具有足够的空间存储10个整数。相比之下,以下方式:
int *pointer;
将pointer
声明为单个指针对象。
重要的是要区分它们中的一个是指针,另一个是实际数组,并且数组和指针密切相关但是不同的东西。然而,说以下没有数组也是不正确的:
pointer = malloc(sizeof (int) * 10);
这段代码的作用是分配一个能容纳10个整数的数组对象。指针pointer
包含该数组第一个元素的地址。(C99草案,第7.20.3节“内存管理函数”)
如果我对您的问题字面上进行解释,答案是否定的:定义数组意味着具有相当特定的含义; 数组定义看起来像这样:
int a[10];
int
值的空间,并将指针存储在该空间的第一个元素中,但它并没有定义一个数组;它只是分配了一个数组。[]
。例如以下代码片段是合法的:int a[10];
for (int i = 0; i < 10; i++) a[i] = 0;
并且
int *a = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) a[i] = 0;
然而,它们之间存在微妙的区别。第一个定义了一个数组,并将其所有元素设置为0。第二个分配存储空间,可以容纳等效类型的数组值,并通过初始化每个元素为0来用于此目的。
值得指出的是,第二个示例没有检查分配错误,这通常被认为是不好的实践。此外,如果未稍后释放分配的存储空间,则构成潜在的内存泄漏。
在标准描述的语言中(与对其进行学究般文字解释的语言不同),malloc(n)的意图是返回一个指针,如果将其强制转换为T*
,则可以将其视为指向T[n/sizeof T*]
的第一个元素的指针。根据N1570 7.22.3的规定:
如果分配成功,则返回的指针适当地对齐,以便可以将其分配给具有基本对齐要求的任何类型对象的指针,然后使用该指针来访问分配的空间中的此类对象或此类对象的数组(直到显式释放空间)。
指针加法和减法的定义并没有讨论对于“适当对齐”的指针进行操作,以允许访问对象数组,而是讨论指向实际数组对象元素的指针。如果程序访问了20个int对象的空间,我认为标准并没有确切地表示结果指针在所有方面都将表现得像指向int[20]元素[0]的指针,而不是例如指向int[4][5]元素[0][0]的指针。当然,一个实现必须非常愚蠢才不允许它被用作其中任何一种,但我认为标准实际上并没有要求这样处理。
n
个整数的内存。就是这样。在这段代码中没有数组的概念。 - Eugene Sh.n>0
,则malloc
调用成功会创建一个匿名数组对象(假设是这样的)。否则,表达式a[0]
或a+0
将无效。 - Keith Thompsonmalloc
分配的空间描述为一个数组。 - M.M