为什么在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.00L ,其中一个普通的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));