我需要在 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)
当 length
是 int
乘积时,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 * col
是 int
数学运算,如果乘积超过 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只是历史悠久。
刚刚注意到 已经介绍了其中的一些内容。
我的教授告诉我以下代码不正确:
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)
length
是 int
乘积时,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 * col
是 int
数学运算,如果乘积超过 INT_MAX
,就会溢出 (UB)。
在第二个中,乘法是使用 size_t
数学完成的。当产品超过 SIZE_MAX
.
SIZE_MAX
通常是 INT_MAX
的两倍,有时是 INT_MAX
.
用更宽的类型引导你的乘法。
// 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只是历史悠久。
刚刚注意到