malloc()可以用来定义数组的大小吗?

时间:2017-01-06 19:26:04

标签: c arrays pointers malloc

这里考虑以下代码示例:

int *a = malloc(sizeof(int) * n);

这段代码可以用来定义一个包含n个整数的数组吗?

5 个答案:

答案 0 :(得分:7)

int *a = malloc(sizeof(int) * n);
  

这段代码可以用来定义一个包含n个整数的数组吗?

这取决于“定义数组”的含义。

声明如下:

int arr[10];

定义一个命名数组对象。您的指针声明和初始化没有。

然而,malloc调用(如果成功并返回非NULL结果,如果 n > 0)将在运行时创建一个匿名数组对象。

但它没有“定义数组a”。 a指针对象的名称。鉴于malloc调用成功,a将指向数组对象的初始元素,但它本身不是数组。

请注意,由于数组对象是匿名的,因此没有任何内容可以应用sizeof,也无法从指针中检索数组对象的大小。如果您需要知道阵列的大小,您需要自己跟踪它。

(有些评论表明malloc调用会分配可以容纳n整数对象但不包含数组的内存。如果是这种情况,那么您将无法访问创建的数组对象的元素。有关指针添加的定义,请参阅N1570 6.5.6p8;有关malloc调用如何创建可访问数组的说明,请参阅7.22.3p1。)

答案 1 :(得分:4)

int *a = malloc(sizeof(int) * n);

假设malloc()调用成功,您可以使用数组表示法(例如a)使用指针a[0] = 5; ,如数组。但是a本身并不是一个数组;它只是一个指向int的指针(它可能是一个可以存储多个int s的内存块。)

您的评论

  

但是我可以在我的程序中使用数组a,否则没有声明

表明这是你主要询问的内容。

用C语言编写

p[i] == *(p + i) == *(i + p) == i[p]

只要ip中的一个是指针类型(p也可以是一个数组 - 因为它将被转换为任何表达式中的指针)。因此,您可以像访问数组一样索引a。但是a实际上是一个指针。

答案 2 :(得分:3)

非常字面地解释你的问题,答案是否定的:“定义数组”意味着非常具体的东西;数组定义类似于:

int a[10];

您发布的内容是内存分配。它分配一个适合保存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来将其用于此目的。

值得指出的是,第二个例子没有检查分配错误,这通常被认为是不好的做法。此外,如果以后不释放分配的存储空间,它将构成潜在的内存泄漏。

答案 3 :(得分:3)

是。这正是malloc()所做的。

重要的区别在于

int array[10];

array声明为一个数组对象,有足够的空间容纳10个整数。相反,以下内容:

int *pointer;

pointer声明为单个指针对象。

重要的是distiguinsh其中一个是指针而另一个是实际数组,并且数组和指针是密切相关的但是是不同的东西。但是,说下面没有数组也是错误的:

pointer = malloc(sizeof (int) * 10);

因为这段代码所做的正是为了分配一个具有10个整数空间的数组对象。指针pointer包含该数组的第一个元素的地址。(C99草案,第7.20.3节“内存管理函数”)

答案 4 :(得分:0)

使用标准所写的语言来描述(不同于它的书呆子字面量所描述的语言),目的是malloc(n)返回一个指针,如果将其转换为a T*可以被视为指向T[n/sizeof T*]的第一个元素的指针。根据N1570 7.22.3:

  

      如果分配成功,则返回的指针将适当对齐,以便可以将其分配给       指向具有基本对齐要求的任何类型的对象的指针,然后使用       在分配的空间中访问此类对象或此类对象的数组(直到该空间)       已明确释放)。

但是,指针加法和减法的定义不是说对“适当对齐”以允许访问对象数组的指针起作用,而是说到指向实际数组对象元素的指针。如果程序访问了20个int对象的空间,我认为标准并没有说得出的指针在所有方面都表现得像是指向{{1}的元素[0]的指针一样},与例如指向int[20]的元素[0] [0]的指针。当然,一个实现必须非常笨拙,不允许它同时使用,但是我认为标准实际上并不需要这种处理。