提问人:Yu Hao 提问时间:6/23/2013 最后编辑:Yu Hao 更新时间:10/1/2021 访问量:40225
为什么在 malloc 中使用 sizeof(*pointer) 更安全
Why is it safer to use sizeof(*pointer) in malloc
问:
鉴于
struct node
{
int a;
struct node * next;
};
要 malloc 一个新结构,
struct node *p = malloc(sizeof(*p));
比
struct node *p = malloc(sizeof(struct node));
为什么?我以为他们是一样的。
答:
23赞
Alok Save
6/23/2013
#1
因为如果在以后的某个时间点指向另一个结构类型,那么你的内存分配语句使用不必改变,它仍然会分配新类型所需的足够内存。它确保:p
malloc
- 您不必在每次更改内存分配语句的类型时都修改内存分配语句。
- 您的代码更可靠,更不容易出现手动错误。
一般来说,不依赖具体类型总是一个好的做法,第一种形式就是这样做的,它不对类型进行硬编码。
79赞
AnT stands with Russia
6/23/2013
#2
它更安全,因为您不必两次提及类型名称,也不必为该类型的“取消引用”版本构建正确的拼写。例如,您不必在
int *****p = malloc(100 * sizeof *p);
将其与基于类型的sizeof
int *****p = malloc(100 * sizeof(int ****));
您必须确保使用了正确数量的 under .*
sizeof
为了切换到另一种类型,您只需要更改一个位置(声明 ),而不是两个。而有投法习惯的人,就要换三个地方。p
malloc
更一般地说,坚持以下准则很有意义:类型名称属于声明,而不是其他任何地方。实际语句应与类型无关。它们应尽可能避免提及任何类型名称或使用任何其他特定于类型的功能。
后者意味着:避免不必要的投射。避免不必要的特定于类型的常量语法(例如,或普通语法就足够了)。避免在 下提及类型名称。等等。0.0
0L
0
sizeof
评论
13赞
Eric Postpischil
6/23/2013
值得一提的是,当类型被改变时,在 p 的声明中改变它就足够了(没有必要在 中改变它)不仅意味着更少的工作,而且出错的机会也更少。因此,这有助于减少错误。malloc
0赞
Josh
12/20/2014
AndreyT,我明白你的意思了,抽象地说......但我敢打赌,在计算机的历史上,从来没有一个平台可以sizeof(int ****) != sizeof(int ***) :)
2赞
AnT stands with Russia
12/20/2014
@Josh:你基本上是说,每次你需要知道指针大小时,你都可以用.是的,它会起作用,但这样的事情应该会产生与无与伦比的左括号相同的未解决的紧张关系(xkcd.com/859sizeof(double *)
)
7赞
ruben2020
6/23/2013
#3
这很方便,因为您可以将其转换为:
struct node *p= malloc(sizeof(*p));
进入这个:
#define MALLOC(ptr) (ptr) = malloc(sizeof(*(ptr) ))
struct node *p;
MALLOC(p);
或者,对于数组:
#define MALLOC_ARR(ptr, arrsize) \
(ptr) = malloc(sizeof(*(ptr) ) * arrsize)
struct node *p;
MALLOC_ARR(p, 20);
为什么这是安全的?因为使用这些宏的用户不太可能犯 AndreyT 概述的错误,就像获取静态数组的大小一样。DIM()
#define DIM(arr) ((sizeof(arr))/(sizeof(arr[0])))
这也更安全,因为用户不需要在多个地方使静态数组大小保持一致。在一个地方设置数组大小,然后只需使用 你就完成了!编译器会为您处理它。DIM()
评论
0赞
chux - Reinstate Monica
2/11/2021
通常宏参数应该有一个 ,所以 --> 。()
.... * arrsize)
... * (arrsize))
下一个:malloc(0) 的意义何在?
评论
sizeof
p = malloc(sizeof*p);
sizeof *p