给定
struct node
{
int a;
struct node * next;
};
为了分配一个新的结构体,请使用malloc函数。
struct node *p = malloc(sizeof(*p));
比...更安全。struct node *p = malloc(sizeof(struct node));
为什么?我以为它们是一样的。
这样更安全,因为您不必两次提及类型名称,并且不必构建 "dereferenced" 版本的正确拼写。例如,在下面的代码中,您无需 "数星星":
int *****p = malloc(100 * sizeof *p);
将此与C语言中基于类型的sizeof
进行比较。
int *****p = malloc(100 * sizeof(int ****));
在使用 sizeof
时,要确保使用了正确数量的 *
。
为了切换到另一种类型,您只需要更改一个地方(即 p
的声明),而不是两个地方。而习惯于对 malloc
的结果进行强制转型的人则需要更改三个地方。
更一般地说,坚持以下准则非常有意义:类型名称应出现在声明中而不是其他任何地方。实际语句应与类型无关。它们应尽可能避免提及任何类型名称或使用任何其他特定于类型的功能。
后者意味着:避免不必要的强制类型转换。避免不必要的特定于类型的常量语法(如 0.0
或 0L
,简单的 0
就足够了)。避免在 sizeof
下提及类型名称。等等。
malloc
中进行更改),这不仅意味着工作量减少,而且错误的可能性也降低了。因此,这有助于减少错误。 - Eric Postpischilsizeof(double *)
。是的,这样做可以实现目的,但像这样的事情应该会产生与未匹配的左括号一样的未解决的紧张感(http://xkcd.com/859/)。 - AnT stands with Russia因为如果在以后的某个时间点 p
被指向另一个结构类型,那么您使用malloc
进行内存分配的语句就不必更改,仍然分配了新类型所需的足够内存。 它确保:
一般来说,不依赖具体类型总是一个好习惯,第一种形式就是这样,它没有硬编码类型。
这很方便,因为你可以将这个转换成:
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()
就可以了!编译器会为您处理。
()
,所以 .... * arrsize)
应该写成 ... * (arrsize))
。 - chux - Reinstate Monica
sizeof
不需要括号:p = malloc(sizeof*p);
- luser droogsizeof *p
。 - Eric Postpischilsizeof *p
不可能是(sizeof *) p
,而且也知道它不是一个sizeof
变量被乘以p
。 - Kaz