I'm a C beginner, and I came across this code while trying to implement a linked list.
struct Node *ptr = malloc(sizeof(*ptr));
The Node struct looks like this:
struct Node {
int data;
struct Node *next;
};
I'm trying to understand the first line. It seems as if malloc(sizeof(*ptr))
already knows the contents of ptr
. What exactly is happening on the left side and is it happening before malloc is called?
CodePudding user response:
It seems as if
malloc(sizeof(*ptr))
already knows the contents ofptr
.
Actually, it doesn't. The sizeof
operator doesn't actually evaluate its operand (unless it's a variable length array), it just looks at its type. This means that ptr
isn't actually dereferenced and is therefore a safe operation.
CodePudding user response:
Only use paranthesis with sizeof
if there's a type you'd like to know the size of. If you have an expression, like *ptr
, it's enough to write:
struct Node *ptr = malloc(sizeof *ptr); // <- no paranthesis
The expression *ptr
dereferences the pointer so it becomes a struct Node
and that's what the sizeof
is returning the size for.
sizeof
expression
- Returns the size, in bytes, of the object representation of the type of expression. No implicit conversions are applied to expression.
It's the same size you get if you do:
struct Node *ptr = malloc(sizeof(struct Node)); // <- paranthesis needed
but the first alternative is often preferable for clarity.
CodePudding user response:
You need to allocate a memory for an object of the type struct Node
declared like
struct Node {
int data;
struct Node *next;
};
So in the call of malloc you need to specify the size of the memory to be allocated for an object of this type. The function malloc returns a pointer to the allocated memory.
So you can write
struct Node *ptr = malloc( sizeof( struct Node ) );
On the other hand, the expression *ptr
has the type struct Node. That is the declared pointer ptr
has the pointer type struct Node *
and dereferencing such a pointer like *ptr
yields an expression of the type struct Node
.
So you may rewrite the above record also like
struct Node *ptr = malloc(sizeof(*ptr));
because in this case sizeof( struct Node )
is equivalent to sizeof( *ptr )
.
That is the compiler needs to know the type of the operand of the operator sizeof
that to determine the size of an object of that type.