0

Recently during a lecture by my tutor about linked lists he declared them like this:

struct asd *head=(struct asd *)malloc(sizeof(struct asd));

I'm wondering what's the difference between the declaration above compared to this:

struct asd *head=malloc(sizeof(struct asd));

Because I've been using the latter for every linked list I make. BTW the language is C.

5 Answers5

2

Fundamentally there is no difference, the issue is malloc returns a void * which then can be set to any other pointer type in C, in C++ it would require an explicit typecast as it was initially done, in C its frown upon to typecast the return from malloc.

So your tutor may have initially learned C++ then C, this is actually quite common now a days.

Samy Vilar
  • 10,800
  • 2
  • 39
  • 34
1

The following is normal and recommended when using C:

struct asd *head = malloc(sizeof(*head));
  1. It is recommended to use sizeof(*head) instead of sizeof(struct asd) because it reduces typos, especially when refactoring code. The two are otherwise equivalent.

  2. It is not recommended to cast the return of malloc, because this has no positive effect. In some cases, casting the result of malloc has a negative effect, since it can suppress an error message for pre-C99 messages when you forget to include <stdlib.h>.

See: Do I cast the result of malloc?

Footnote: The only plausible reason to cast the result of malloc is so you can write code that is simultaneously C and C++. But please don't do write code that is both C and C++, that's kind of crazy.

Community
  • 1
  • 1
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • By casting you mean the first declaration. I'm a bit rusty on C terminologies. Also I have no plans to that is both C and C++. I'm not yet ready to go to a mental institute. Anyways thanks for the answer. – Default_John_Smith_Default Sep 14 '12 at 05:10
0

malloc returns a void* pointer so your lecturer was using the correct syntax and explicitly casting to the correct type. What you were doing worked because the compiler automatically converted it for you. I assume you used MSVC because GCC would have warned you about this (I think).

OJay
  • 4,763
  • 3
  • 26
  • 47
  • 2
    No, the implicit cast from `void *` to any data pointer type should not cause a warning from any compiler. Perhaps you are thinking of C++? – Dietrich Epp Sep 14 '12 at 05:01
  • Yeah, I did think of C++. Is it the same between ANSI C and C99? – OJay Sep 14 '12 at 05:19
  • 1
    By "ANSI C" you may want to say C90 or C89, since C99 is also an ANSI standard. All versions of C that have `void *` allow it to be implicitly cast to any data pointer type, that is the entire reason that `void *` exists in the first place. Old C versions had no `void *` and `malloc` returned `char *`, so the cast was necessary... but these are really old, pre-ANSI versions. – Dietrich Epp Sep 14 '12 at 05:24
0

There isn't really a difference. Malloc allocates memory of a particular size (the number of bytes for the struct asd). This occurs in both cases. The difference is that the pointer (which is just a memory address) is cast in the first example and not cast in the second.

Casting a pointer doesn't actually 'do anything'. It is syntactic sugar which is designed to make it easier for you (and the compiler) to think of the pointer in a particular way. Again, in this example, it makes no difference.

I would personally prefer the first approach that your lecturer used since it is explicit. You are explicitly saying that the memory address returned by malloc points to a struct asd. Although internally, a pointer is a pointer is a pointer. Explicit is almost always a good thing in C.

Brett
  • 4,066
  • 8
  • 36
  • 50
  • 1
    The first approach will not generate an error in pre-C99 compilers when you forget to include ``, and it also duplicates code, so it is generally frowned upon to cast the result of `malloc` in C. In C, being too explicit is generally a bad idea because it will suppress warnings, since the compiler trusts you know what you're doing if you're so explicit. – Dietrich Epp Sep 14 '12 at 05:06
  • @DietrichEpp: I'm explicit because I believe developers should be thinking about the automatic casts that are happening and working with the compiler to produce the expected result. I encourage new developers to be very much aware of automatic behavior: whether the developer chooses to be explicit or not is a personal preference at that point, in my opinion. – Brett Sep 14 '12 at 05:10
  • 1
    On the other side of things, any implicit casts will be checked for correctness by the compiler, but explicit casts will not. The only way to check the correctness of an explicit cast is to have a human being look at it and think for a moment, but with implicit casts the compiler is able to catch a large variety of errors. The main exception here is implicit casts to unsigned integers, which generally give surprising results. Using an explicit cast is often an easy way to locally disable diagnostics. – Dietrich Epp Sep 14 '12 at 05:18
0

malloc() returns a void pointer and in C a void pointer can be assigned to any pointer without an explicit cast. so the explicit cast(#1) as such is not needed.

In fact, Some programmers would advice avoiding the cast(#2) to avoid an obscure usability error.

If you forget to include stdlib.h. Compilers will assume that malloc() is a function returning int, and will convert the void* pointer returned by malloc() to int due to the explicit cast. On some platforms, size of an int and size of pointers may not be same and so such undesired type conversions may lead to data corruption.

Personally, I don't find this much of an reason, rather similar philiosphy to the age old Yoda condition.

Alok Save
  • 202,538
  • 53
  • 430
  • 533