Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instead of using sizeof(type), use sizeof *p,is it safe and correct?

Tags:

c

malloc

Is this safe to use,This code compiled with gcc 4.9.2 without any error or warning

widget *p;
...
p = malloc(sizeof *p);

I found this on SEI CERT C Coding Standard website.

Click here -- no type mismatch issues, no need for casting. You allocate the right amount of memory every time.


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); 

like image 402
Malik Ji Avatar asked Dec 08 '22 11:12

Malik Ji


1 Answers

The sizeof operator has the following definition

sizeof unary-expression
sizeof ( type-name )

Thus in this declaration

widget_t *p = malloc(sizeof *p);

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 ) );

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.

In C there is no need to cast the pointer returned from malloc to the type of the assigned lvalue because a pointer of the type void * may be assigned to pointer to object of any type. It is sometimes used (and moreover sometimes useful) to make the program self-documented.

like image 99
Vlad from Moscow Avatar answered Dec 10 '22 00:12

Vlad from Moscow