使用起来安全吗,此代码使用gcc 4.9.2编译,没有任何错误或警告
widget *p;
...
p = malloc(sizeof *p);
Run Code Online (Sandbox Code Playgroud)
我在SEI CERT C编码标准网站上找到了它。
单击此处 -没有类型不匹配的问题,无需强制转换。您每次分配正确的内存量。
struct widget;
typedef struct widget widget_t;
struct gadget;
typedef struct gadget gadget_t;
widget_t *newWidget(void)
{
widget_t *p = malloc(sizeof *p);
if (p)
/* initialize members of *p as necessary */
return p;
}
gadget_t *newGadget(void)
{
gadget_t *p = malloc(sizeof *p);
if (p)
/* initialize members of *p as necessary */
return p;
}
void deleteWidget(widget_t **p)
{
/* delete any subelements of *p */
free(*p);
*p = NULL;
}
void deleteGadget(gadget_t **p)
{
/* delete any subelements of *p */
free(*p);
*p = NULL;
}
...
widget_t *p = newWidget();
gadget_t *g = newGadget();
if (p)
/* do stuff with p */
if (g)
/* do stuff with g */
...
deleteWidget(&p);
deleteGadget(&g);
Run Code Online (Sandbox Code Playgroud)
It's a good coding practice!
Imagine this code
struct structv1 *p1 = malloc(sizeof (struct structv1));
struct structv1 *p2 = malloc(sizeof *p2);
Run Code Online (Sandbox Code Playgroud)
gets changed to
struct structv2 *p1 = malloc(sizeof (struct structv2));
// ^^^^^^^^ ^^^^^^^^^^^^^^^^^
// two changes! maybe the programmer forgets one of them
struct structv2 *p2 = malloc(sizeof *p2);
// ^^^^^^^^
// one change only. the argument to malloc is already correct
Run Code Online (Sandbox Code Playgroud)
The sizeof operator has the following definition
sizeof unary-expression
sizeof ( type-name )
Run Code Online (Sandbox Code Playgroud)
Thus in this declaration
widget_t *p = malloc(sizeof *p);
Run Code Online (Sandbox Code Playgroud)
there is used the first form of the operator where the expression *p is an unary expression and has the type of widget_t.
Thus these declarations
widget_t *p = malloc(sizeof *p);
widget_t *p = malloc(sizeof( widget_t ) );
Run Code Online (Sandbox Code Playgroud)
are totally equivalent.
The first declaration is preferable because the expression in the sizeof operator does not depend on the actual type. That is the type of the pointer can be changed but the declaration will be valid without any other changes.
在C语言中,不需要将malloc返回的指针转换为所分配的左值的类型,因为可以将void *类型的指针分配给任何类型的对象的指针。有时使用它(并且有时是有用的)来使程序具有自说明性。