How does this 'sizeof(*area)' work?

X

Xiangliang Meng

Hi, all.

How does this 'sizeof(*area)' work? I think the reason is the sentence in
C99: If the operand has type ¡®¡®pointer to type¡¯¡¯, the result has type
¡®¡®type¡¯¡¯, but I'm not sure. Could someone ensure me or explain it more?

In linux\mm\vmalloc.c,
struct vm_struct * get_vm_area(unsigned long size, unsigned long flags)
{
unsigned long addr;
struct vm_struct **p, *tmp, *area;

area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL); // I'm
wondering how this sizeof works.
if (!area)
return NULL;
...
}

According to C99:

sizeof unary-expression
sizeof ( type-name )

4 The unary * operator denotes indirection. If the operand points to a
function, the result is
a function designator; if it points to an object, the result is an lvalue
designating the
object. If the operand has type ¡®¡®pointer to type¡¯¡¯, the result has type
¡®¡®type¡¯¡¯. If an
invalid value has been assigned to the pointer, the behavior of the unary *
operator is
undefined. 72)

NOTE: Among the invalid values for dereferencing a pointer by the unary *
operator are a null pointer, an
address inappropriately aligned for the type of object pointed to, and the
address of an automatic
storage duration object when execution of the block with which the object is
associated has
terminated.

Thanks.

Best Regards,

Xiangliang Meng
 
K

Kelsey Bjarnason

[snips]

struct vm_struct **p, *tmp, *area;

area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL); // I'm

No idea what kmalloc is. However, let's make it simpler:

int *x = malloc( sizeof(*x) );

X is a pointer-to-int. Hence, the object(s) it points to are of type int.
Hence, *x must be an int, hence sizeof( *x ) must mean sizeof(int).

This also means that things such as x[3] = 19; will work correctly, since
x, being a pointer-to-int, will be indexed in such a manner that each
element is one int wide.

Why would one do this, instead of using sizeof(int)? Simple: suppose we
change our code:

double *x = malloc( sizeof(*x) );

The sizeof automagically adapts to allocating space for the new type. If
we'd used explicit types instead of *x (eg sizeof(int)), it makes it
easier to overlook the second item and produce incorrect code such as:

double *x = malloc( sizeof(int) );
 
K

Keith Thompson

Kelsey Bjarnason said:
[snips]

struct vm_struct **p, *tmp, *area;

area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL); // I'm

No idea what kmalloc is. However, let's make it simpler:

int *x = malloc( sizeof(*x) );

X is a pointer-to-int. Hence, the object(s) it points to are of type int.
Hence, *x must be an int, hence sizeof( *x ) must mean sizeof(int).

This also means that things such as x[3] = 19; will work correctly, since
x, being a pointer-to-int, will be indexed in such a manner that each
element is one int wide.

Why would one do this, instead of using sizeof(int)? Simple: suppose we
change our code:

double *x = malloc( sizeof(*x) );

The sizeof automagically adapts to allocating space for the new type. If
we'd used explicit types instead of *x (eg sizeof(int)), it makes it
easier to overlook the second item and produce incorrect code such as:

double *x = malloc( sizeof(int) );

Perhaps the piece of the puzzle that the OP missed is that the operand
of sizeof is not evaluated. (There is an exception to this, but it
involves C99 VLAs, which aren't relevant to this example.) Looking at
your simple example again:

int *x = malloc(sizeof(*x));

Normally, any use of *x in the initialization of x would be Very Bad,
because x hasn't been initialized yet. But in the context of a sizeof
operator, the expression is examined only to determine its type.

BTW, the inner parentheses aren't strictly necessary, though they're
allowed. The above is equivalent to:

int *x = malloc(sizeof *x);

Some might prefer to use the parentheses because the latter form looks
too much like a multiplication. Use whichever form you like, but be
prepared to understand either one.
 
K

Kelsey Bjarnason

[snips]

Perhaps the piece of the puzzle that the OP missed is that the operand
of sizeof is not evaluated.
....

BTW, the inner parentheses aren't strictly necessary, though they're
allowed. The above is equivalent to:

Indeed, on both points. I tend to use the inner parentheses for what I
regard as clarity; YMMV.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top