我需要在 malloc 中的数组长度之后放置 sizeof 吗?

Do I need to put sizeof after array length in malloc?

我的教授告诉我以下代码不正确:

int *array = malloc(sizeof *array * length);

它应该是:

int *array = malloc(length * sizeof(int));

他说你应该把 sizeof 的类型括在括号之间,并且长度 必须 出现在 sizeof 运算符之前。他说我可以用*array代替int,但他更喜欢后者

我最大的问题是为什么在调用 malloc 时长度必须在大小之前,还有为什么在 sizeof 中使用指针类型而不是指针本身更可取。

他还提到转换(即 (int*))是可取的,但我不确定为什么有必要。

sizeof运算符定义如下

sizeof unary-expression

所以这一行

int *array = malloc(sizeof *array * length);

相当于

int *array = malloc( ( sizeof *array ) * length);

但原句虽然正确,但不太清楚。所以最好的写法是

int *array = malloc( length * sizeof *array );

甚至更好

int *array = malloc( length * sizeof( *array ) );

你也可以这样写

int *array = malloc(length * sizeof(int));

但是如果动态分配数组的元素类型将被更改,那么您需要在两个地方进行更改,例如

long *array = malloc(length * sizeof(long));
^^^^                                 ^^^^

如果您忘记更改 sizeof 表达式中的类型,那么可能会出现在大型项目中很难发现的错误。

这一行

int *array = malloc( length * sizeof( *array ) );

您只需要在一个地方进行更改

long *array = malloc( length * sizeof( *array ) );
^^^^

所以这个声明不太容易出错。

两者都有效,但许多资深程序员会更喜欢您的方法。

使用 sizeof *array 而不是 sizeof(int) 的优点是,如果您碰巧更改了 array 的类型,那么您不需要更改分配方式.

也没有技术原因首先乘以 length 而不是元素大小。如果有的话,在查看对 malloc 的调用时,您首先想知道的是您分配了多少“东西”,因此从可读性的角度来看,将长度放在首位可能更有意义。另一方面,因为 sizeof 运算符的结果是无符号的,所以如果你有多个数组维度,将它放在第一位可以保证数学是用无符号类型完成的。

您也 不想 转换 malloc 的 return 值,因为这会掩盖代码中的其他错误,特别是缺少 #include <stdlib.h>

第一个唯一的问题是这个(我从 'array' 改成了一个没有如此明显含义的名字)

int *twoodle = malloc(sizeof *twoodle * length);

int *twoodle = malloc(sizeof *twoodle);

两者都有效,将编译,但只有一个是正确的。而且光看是无法分辨的

我知道其他格式也有同样的问题但是人们认为(上面已经说过)“所以这个声明不太容易出错。”。但是你仍然可以在这里犯错误

要点是,确保您的 mallocs 是正确的 (duh)

lengthint 乘积时,

int *array = malloc(length * sizeof(int)); 会带来另一个问题。

考虑

  int *alloc_array(int rows, int col) {
    int *array = malloc(rows * col * sizeof *array);  // Overflow more likely
    return array;
  }

对比

  int *array = malloc(sizeof *array * rows * col); // Better

首先,rows * colint 数学运算,如果乘积超过 INT_MAX,就会溢出 (UB)。

在第二个中,乘法是使用 size_t 数学完成的。当产品超过 SIZE_MAX.

时发生溢出

SIZE_MAX 通常是 INT_MAX 的两倍,有时是 INT_MAX.

的 8,000,000,000 倍

用更宽的类型引导你的乘法。


// Use this in the stuck in the 90s prof's class.
int *array = (int *) malloc(length * sizeof(int));

// Otherwise, use
int *array = malloc(sizeof *array * length);

意识到使用 C,从 time-to-time 开始,您将不得不按照一些神秘的标准进行编码。 (IMO,通常不是出于技术原因。)所有语言都有这个问题。 C只是历史悠久。


刚刚注意到 已经介绍了其中的一些内容。