为什么在malloc中使用sizeof(*指针)更安全
特定
struct node { int a; struct node * next; };
为了build立一个新的结构,
struct node *p = malloc(sizeof(*p));
比…更安全
struct node *p = malloc(sizeof(struct node));
为什么? 我以为他们是一样的。
这是更安全的,因为您不必提及types名称两次,也不必为“取消引用”的types构build正确的拼写。 例如,你不必“数星星”
int *****p = malloc(100 * sizeof *p);
将它与基于types的sizeof
进行比较
int *****p = malloc(100 * sizeof(int ****));
你也要确保你在sizeof
下使用了正确的数字*
。
为了切换到另一个types,你只需要改变一个地方( p
的声明)而不是两个。 而那些习惯了malloc
结果的人则必须换三个地方。
更一般地说,坚持以下原则是很有意义的:types名称属于声明而不属于其他地方。 实际的语句应该是types无关的。 他们应该尽可能避免提及任何types名称或使用任何其他types特定的function。
后者的意思是:避免不必要的转换。 避免不必要的types特定的常量语法(如0.0
或0L
,其中一个普通的0
就足够了)。 避免在sizeof
下提及types名称。 等等。
因为如果在稍后的时间点p
指向另一个结构types,那么使用malloc
内存分配语句不必改变,它仍然分配了新types所需的足够的内存。 它确保:
- 每次更改分配内存的types时 ,都不必修改内存分配语句。
- 您的代码更健壮,更不容易出现手动错误。
总的来说,不依赖具体types总是一个好的做法,第一种forms就是这样做的,它不会硬编码一种types。
这很方便,因为你可以转换这个:
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);
为什么这是安全的? 因为使用这些macros的用户不太可能会犯AndreyT勾画的错误,就像在DIM()
的情况下获得静态数组的大小一样。
#define DIM(arr) ((sizeof(arr))/(sizeof(arr[0])))
这也比较安全,因为用户不需要在几个地方使静态数组大小一致。 将数组大小设置在一个地方,然后使用DIM()
完成! 编译器负责为您服务。
它不直接影响安全,但可以声称它可以防止未来版本中的错误。 另一方面,很容易忘记那个小小的*
。 如何使它成为一种types,它肯定是更清洁的。
typedef struct node { int a; struct node * next; } node_t;
那么你可以这样做:
node_t *p = malloc(sizeof(node_t));