52

给定

struct node
{
     int a;
     struct node * next;
};

为了 malloc 一个新的结构,

struct node *p = malloc(sizeof(*p));

比安全

struct node *p = malloc(sizeof(struct node));

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

4

3 回答 3

76

它更安全,因为您不必两次提及类型名称,也不必为类型的“取消引用”版本构建正确的拼写。例如,您不必在

int *****p = malloc(100 * sizeof *p);

将其与基于类型的sizeofin进行比较

int *****p = malloc(100 * sizeof(int ****));

你必须确保你使用了正确数量的*under sizeof

为了切换到另一种类型,您只需更改一个位置(的声明p)而不是两个。而有投出结果习惯的人malloc要换三个地方。

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

后者意味着:避免不必要的演员表。避免不必要的特定于类型的常量语法(例如0.00L普通0就足够的地方)。避免在sizeof. 等等。

于 2013-06-23T07:44:04.750 回答
22

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

  • 您不必在每次更改它为其分配内存的类型时修改内存分配语句。
  • 您的代码更健壮,更不容易出现人为错误。

一般来说,不依赖具体类型总是一个好习惯,第一种形式就是这样做的,它不会对类型进行硬编码。

于 2013-06-23T07:43:34.747 回答
7

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

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()就完成了!编译器会为您处理它。

于 2013-06-23T10:00:54.410 回答