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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17258647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:45:38  来源:igfitidea点击:

Why is it safer to use sizeof(*pointer) in malloc

cmalloc

提问by Yu Hao

Given

给定的

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

To malloc a new structure,

要 malloc 一个新结构,

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

is safer than

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

Why? I thought they are the same.

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

回答by AnT

It is safer becuse you don't have to mention the type name twice and don't have to build the proper spelling for "dereferenced" version of the type. For example, you don't have to "count the stars" in

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

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

Compare that to the type-based sizeofin

与此相比,该型为主sizeof

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

where you have too make sure you used the right number of *under sizeof.

在那里你也确保你使用了正确数量的*under sizeof

In order to switch to another type you only have to change one place (the declaration of p) instead of two. And people who have the habit of casting the result of mallochave to change three places.

为了切换到另一种类型,您只需更改一个地方( 的声明p)而不是两个。并且习惯于转换结果的malloc人必须改变三个地方。

More generally, it makes a lot of sense to stick to the following guideline: type names belong in declarations and nowhere else. The actual statements should be type-independent. They should avoid mentioning any type names or using any other type-specific features as much as possible.

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

The latter means: Avoid unnecessary casts. Avoid unnecessary type-specific constant syntax (like 0.0or 0Lwhere a plain 0would suffice). Avoid mentioning type names under sizeof. And so on.

后者意味着:避免不必要的强制转换。避免不必要的特定于类型的常量语法(例如0.00L在普通的地方0就足够了)。避免在 下提及类型名称sizeof。等等。

回答by Alok Save

Because if at some later point in time pis made to point to another structure type then your memory allocation statement using mallocdoesn't have to change, it still allocates enough memory required for the new type. It ensures:

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

  • You don't have to modify the memory allocation statement every time you change the typeit allocates memory for.
  • Your code is more robust and less prone to manual errors.
  • 每次更改内存分配语句的类型时,您不必修改它。
  • 您的代码更健壮,更不容易出现手动错误。

In general it is always a good practice to not rely on concrete types and the the first form just does that ,it doesn't hard code a type.

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

回答by ruben2020

It is convenient, because you can convert this:

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

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

Into this:

进入这个:

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

struct node *p;
MALLOC(p);

Or, for an array:

或者,对于数组:

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

struct node *p;
MALLOC_ARR(p, 20);

And why is this safe? Because the user who uses these macros would be less likely to make mistakes which were outlined by AndreyT, just as in the case of DIM()to get the size of a static array.

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

#define DIM(arr)   ((sizeof(arr))/(sizeof(arr[0])))

This is also safer, because the user does not need to make the static array size consistent in several places. Set the array size in one place and then just use the DIM()and you're done! The compiler takes care of it for you.

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