为什么在malloc中使用sizeof(*pointer)更安全

Yu *_*Hao 41 c malloc

特定

struct node
{
     int a;
     struct node * next;
};
Run Code Online (Sandbox Code Playgroud)

要malloc一个新的结构,

struct node *p = malloc(sizeof(*p));
Run Code Online (Sandbox Code Playgroud)

比...更安全

struct node *p = malloc(sizeof(struct node));
Run Code Online (Sandbox Code Playgroud)

为什么?我以为他们是一样的.

AnT*_*AnT 62

更安全的是,您不必两次提及类型名称,也不必为该类型的"解除引用"版本构建正确的拼写.例如,您不必"计算星星"

int *****p = malloc(100 * sizeof *p);
Run Code Online (Sandbox Code Playgroud)

与此相比,该型为主sizeof

int *****p = malloc(100 * sizeof(int ****));
Run Code Online (Sandbox Code Playgroud)

在这里你有太多确保你使用正确的号码*sizeof.

要切换到另一种类型,您只需要更改一个地方(声明p)而不是两个.那些有铸造结果的malloc人必须改变三个地方.

更一般地说,坚持以下准则是很有意义的:类型名称属于声明而不是其他地方.实际的陈述应该是与类型无关的.他们应该尽可能避免提及任何类型名称或使用任何其他类型特定的功能.

后者意味着:避免不必要的演员阵容.避免不必要的类型特定的恒定的语法(例如0.00L其中一个普通的0就足够了).避免提及下面的类型名称sizeof.等等.

  • 值得一提的是,当类型被改变时,在p的声明中改变它就足够了(不需要在'malloc`中改变它)不仅意味着工作量减少,而且工作量减少错误的机会.因此,这有助于减少错误. (12认同)
  • @Josh:您基本上是在说每次需要知道指针大小时,您都可以使用 `sizeof(double *)`。是的,它会起作用,但是这样的事情应该会产生与无与伦比的左括号相同的未解决的张力(http://xkcd.com/859/) (2认同)

Alo*_*ave 19

因为如果在某个稍后的时间p点指向另一个结构类型,那么使用的内存分配语句malloc不必更改,它仍然分配新类型所需的足够内存.它确保:

  • 每次更改为其分配内存的类型时,都不必修改内存分配语句.
  • 您的代码更强大,不易出现手动错误.

一般来说,不依赖于具体类型总是一个好习惯,而第一种形式就是这样做,它并不是硬编码类型.


rub*_*020 7

这很方便,因为您可以将其转换为:

struct node *p= malloc(sizeof(*p));
Run Code Online (Sandbox Code Playgroud)

进入这个:

#define MALLOC(ptr)   (ptr) = malloc(sizeof(*(ptr) ))

struct node *p;
MALLOC(p);
Run Code Online (Sandbox Code Playgroud)

或者,对于数组:

#define MALLOC_ARR(ptr, arrsize) \
       (ptr) = malloc(sizeof(*(ptr) ) * arrsize)

struct node *p;
MALLOC_ARR(p, 20);
Run Code Online (Sandbox Code Playgroud)

为什么这是安全的?因为使用这些宏的用户不太可能犯 AndreyT 概述的错误,就像DIM()获取静态数组的大小一样。

#define DIM(arr)   ((sizeof(arr))/(sizeof(arr[0])))
Run Code Online (Sandbox Code Playgroud)

这也更安全,因为用户不需要在几个地方使静态数组大小保持一致。在一个地方设置数组大小,然后使用DIM()就完成了!编译器会为您处理它。