3
struct node* new_node =
            (struct node*) malloc(sizeof(struct node));

I don't understand the * here : ...(struct node*) malloc(siz... First, the * belongs to node or malloc? what does it mean? how pointers got anything to do with the memory function malloc? I'm really confused with the * location

Thanks

Segev
  • 19,035
  • 12
  • 80
  • 152
  • 4
    Its an (unnecessary) cast. The return value of `malloc()` is a `void*`. See http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – hmjd Aug 22 '12 at 07:56
  • 2
    "how pointers got anything to do with the memory function" - quite everything – Bartek Banachewicz Aug 22 '12 at 07:57

6 Answers6

6

A type name in parenthesis (such as (struct node *)) in C is called a "cast". It's a way to alter the type of an expression into the named type, and is commonly used with pointers.

However, this is code that ignores the advice in Do I cast the result of malloc. The cast is not needed here, making this (in my opinion, and perhaps not very surprisingly if you've followed that link) rather bad code.

The best way to write this allocation is:

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

This mentions the type exactly once, drops the cast which can introduce errors and is both pointless and cumbersome to read, and avoids introducing brittleness when specifying how much memory to allocate. It's win, win win.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • 1
    In my opinion, `node_t* new_node = malloc (sizeof (node_t));` is far less of an eye sore. – Lundin Aug 22 '12 at 09:18
2
struct node     <= type
*new_node       <= pointer named new_node (of type struct node)
=               <= assignment
(struct node *) <= cast to pointer of type struct node
malloc(SIZE)    <= returns pointer of type void, thus needs cast
jacekmigacz
  • 789
  • 12
  • 22
  • `=` in this example is not assignment, it's part of the initialization syntax. Not that it makes much practical difference in C, but that's what the C grammar calls it. – Steve Jessop Aug 22 '12 at 08:39
  • I'd rather say that the type is `struct node*` (a pointer to node). Also, you are incorrect about a void pointer needing a cast. – Lundin Aug 22 '12 at 08:44
  • @Lundin: grammatically, `struct node` is the *type-specifier*, and `*new_node` is the *declarator*. Of course it's true that as a consequence, the type of `new_node` is `struct node*`, but nevertheless in a declaration that `*` isn't part of the type-specifier. Hence for example `struct node *ptr, instance;`. – Steve Jessop Aug 22 '12 at 09:44
  • @SteveJessop Which is why it is a bad idea to declare several variables on a single line. If you declare each variable on a line of its own, then my statement holds, and then you don't need to know or worry about C standard formal gibberish. – Lundin Aug 22 '12 at 10:52
  • @Lundin: sure, alternatively you can read and understand the standard ;-p There are other complex declarations where the simplified notion of "type followed by name of object" breaks down, for example pointers-to-array. So IMO it's worth knowing the actual grammar (by which I mean, mostly knowing it and being able to look up awkward details), rather than hoping to get away with a simplified grammar and always demanding that everyone else use enough typedefs that the simplified version remains correct. – Steve Jessop Aug 22 '12 at 11:12
  • @SteveJessop The problem with the formal grammar (as specified in 6.7 of the standard) is that it doesn't seem to cover all special cases either. Do try to declare an array pointer, or a function pointer, or just a plain `const int* const` by looking at that formal syntax gibberish. There is just no way you will succeed, not even the person who wrote it will. – Lundin Aug 22 '12 at 11:53
  • @Lundin: just to take your last example, `const int *const foo;`, the type-specifier is `const int` and the declarator is `*const foo`. It matches the *declarator* production from 6.7.5, with `*const` as the *pointer* (a `*` followed by a *type-qualifier-list*) and `foo` as the *direct-declarator* (just an *identifier*). I don't think it's worth reading the formal grammar until you've seen some code examples, but I do think it's worth knowing how the C language is defined. Even if it's not worth knowing for you, it's not gibberish. – Steve Jessop Aug 22 '12 at 12:55
  • Heh, my mistake, the type-specifier is `int`. The first `const` is a type-qualifier appearing in the *declaration-specifiers* of this *declaration* (6.7). Anyway, I dispute "there is just no way that you will succeed". Those who can successfully use the grammar to parse correct C code include me on a good day, the authors of the standard, and some C compilers. – Steve Jessop Aug 22 '12 at 13:06
1

(struct node*) is cast, which is an explicit type conversion. The * belongs to struct node, stating that the type requested is a pointer to a struct node variable. malloc() always returns a void*, a void pointer.

The function definition of malloc is void* malloc (size_t size); (and the * belongs to void in that case as well).

The person who wrote the code posted in your question casted this void pointer into a struct node*. Why they did this isn't clear, they were either confused about how pointer casts in C work and also unaware of the dangers with such casts, or the code was written for C++.

A void pointer in the C language is a generic pointer type that can be converted to any other pointer type, without a cast (1).

In C++ however, you must always have a cast when converting a void pointer, because C++ has stricter type conversion rules than C and enforces an explicit conversion.

Casting the result of malloc() in C is dangerous and considered a bug (2), because unless the correct function prototype is provided through #include , then the compiler default behavior kicks in and it will incorrectly believe that malloc returns int. Depending on pointer and integer widths of the particular system, it may work just fine, or it may cause the program to crash and/or leak memory.

Casting the result of malloc() in C++ is however necessary.


References:

  1. ISO 9899:2011 6.3.2.3/1.
  2. Specifically, what's dangerous about casting the result of malloc?
Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • "Typecasting" is more correctly called "casting". And "explicit [type]cast" is redundant; all casts are explicit, and an implicit conversion is not a cast. – Keith Thompson Aug 22 '12 at 08:41
  • @KeithThompson Alright that's rather picky, but I updated the post so it now uses the formal terms used in the C standard: _cast_, _implicit conversion_ and _explicit conversion_. I'm not quite sure what difference that makes for a beginner programmer, however. – Lundin Aug 22 '12 at 08:50
  • I took it from here: http://www.geeksforgeeks.org/archives/860 Is that C++ or just a bad written code? – Segev Aug 22 '12 at 09:09
  • @MikaStern That's most definitely C. And apart from the malloc cast, the code actually looks pretty well-written. – Lundin Aug 22 '12 at 09:16
0

The * is for the type. The type in here is a struct node* (a pointer to a struct node).

It is not "connected" to the malloc function, it is "connected" to the type. The malloc() returns a pointer, and thus you assign the return value as a pointer as well.

amit
  • 175,853
  • 27
  • 231
  • 333
0

It is just type casting.

malloc returns a void pointer(pointer which does not have any type). (struct node *) means you are assining a type to the void pointer returned by malloc. also see this

Community
  • 1
  • 1
Vijay
  • 65,327
  • 90
  • 227
  • 319
0

It is just a type casting. Actually malloc function returns void pointer (void *) , meaning it is not specific to any data structure or data type. It returns a generic pointer. By type casting we make the returned value specific, in this case (struct node *) which is a pointer to node type of struct.

In simple terms we can say we are converting the void pointer (void *) into struct pointer (struct node *).

Anup H
  • 549
  • 7
  • 10