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

时间:2013-06-23 07:42:30

标签: c malloc

鉴于

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

要对新结构进行malloc,

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

更安全
struct node *p = malloc(sizeof(struct node));

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

4 个答案:

答案 0 :(得分:60)

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

中“计算星星”
int *****p = malloc(100 * sizeof *p);

将其与

中基于类型的sizeof进行比较
int *****p = malloc(100 * sizeof(int ****));

您也可以确保在*下使用了正确数量的sizeof

要切换到其他类型,您只需更改一个位置(p的声明)而不是两个。那些习惯于施放malloc结果的人必须改变三个地方。

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

后者意味着:避免不必要的演员阵容。避免使用不必要的特定于类型的常量语法(例如0.00L,其中普通0就足够了。避免在sizeof下提及类型名称。等等。

答案 1 :(得分:19)

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

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

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

答案 2 :(得分: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()即可完成!编译器会为您处理它。

答案 3 :(得分:0)

它不会直接影响安全性,但可以声称它可以防止未来修订中的错误。另一方面,很容易忘记那个*。如何使它成为一种类型,它肯定更清洁。

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

然后你可以这样做:

node_t *p = malloc(sizeof(node_t));