0

I would like to know if there's a real difference between this:

c = (struct_t *) malloc(sizeof(struct_t));

and this

c = malloc(sizeof(struct_t *));

Besides avoid the cast, is the compiler takes any advantage in the second form respect the first? Or the two ways are completely the same and is just a "aesthetical" question ?

Kyrol
  • 3,475
  • 7
  • 34
  • 46
  • hmmm... I have a `typedef struct struct_t { .... } struct_t;` and I declare `struct_t * c;` – Kyrol Mar 12 '13 at 10:41
  • ahhh okok. You're right. Probably the second form could be: `c = malloc(sizeof(*c));`. Isn't it? – Kyrol Mar 12 '13 at 10:46
  • 2
    @Kyrol Use `c = malloc(sizeof(struct_t));` and forget about the other cases, they likely don't make sense for what you are attempting to do. – Lundin Mar 12 '13 at 10:49
  • So I have just to avoid the cast. Right? But are you sure that if I declare c as a pointer, your form is correct? I'd like to know why is correct. :) – Kyrol Mar 12 '13 at 10:52

5 Answers5

6

The first allocates sizeof(struct_t) bytes, the second sizeof(struct_t*) bytes.

Apart from that, there is no difference in what malloc does, whether you cast the result or not. Casting the result makes the code acceptable to C++ compilers, but it can hide the mistake of not including stdlib.h, therefore it is widely preferred to not cast the result in C.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • So, for this reason, is better if I use the first or the second? – Kyrol Mar 12 '13 at 10:23
  • 2
    Well, you have to use the correct size. Then, if you have that, I prefer the version without cast, since the cast is unnecessary (and can hide errors if you don't compile strictly to a standard that forbids implicit declarations). C++ people often prefer the one with the cast. – Daniel Fischer Mar 12 '13 at 10:30
  • 2
    C++ people should use `new`, compile C code with a C compiler, and link it to their C++ project... – autistic Mar 12 '13 at 10:37
  • ... and malloc isn't the only reason to compile C code with a C compiler rather than a C++ compiler. – autistic Mar 12 '13 at 10:38
  • I'm not using C++, just C. – Kyrol Mar 12 '13 at 10:44
  • 1
    @modifiablelvalue The new reigning opinion among C++ people is that they shouldn't even use `new`, if my impressions do not mislead me. I strongly agree that C code should be compiled with a C compiler. – Daniel Fischer Mar 12 '13 at 11:01
  • @DanielFischer Has a concept only slightly different to C#'s `stackalloc` been adopted in C++, which promises some degree of "compatibility"? – autistic Mar 12 '13 at 11:34
5

The two are totally different. The first allocates an instance of the struct, whereas the second allocates a pointer to the struct.

In general, they won't even allocate the same number of bytes.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
3

No, they are not the same. The latter allocates 4 or 8 bytes of space for a pointer to struct, the first allocates enough space for the struct it self.

When sizeof(struct_t) is small enough, and when the malloc allocates actually more than requested, the user may not see the difference.

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
  • Ok, I understand. I always used the first form, but recently I saw also the second form and I wanted to understand if there was any big differences. Thanks. – Kyrol Mar 12 '13 at 10:26
  • Only rarely there's need to allocate space for a _single_ pointer. It's more like the interface needs to be redesigned. – Aki Suihkonen Mar 12 '13 at 14:43
1

Two forms are different. They both allocate memory, but with different amounts. General rule is as follows: when allocating type T, the result of malloc shall be casted to T*.

void sample1()
{
    struct pollfd *pfd = (struct pollfd*)malloc(sizeof(struct pollfd));
    // pfd is points to a memory with a size of struct pollfd
    ...
    free(pfd);
}

void sample2()
{
    struct pollfd *pfd = (struct pollfd*)malloc(sizeof(*pfd));
    // same as above, but uses variable type instead
    free(pfd);
}

If you specify incorrect type in malloc argument, generally that will lead to buffer overrun problems:

void sample3()
{
    struct x *px= (struct x*)malloc(sizeof(struct x*));
    x->field = 5; //<< error, as allocated only 4 or 8 bytes depending on pointer size
}
Valeri Atamaniouk
  • 5,125
  • 2
  • 16
  • 18
0

Both are different.

Usually malloc returns (void*). So you want to typecast void* to (struct_t*).

sujin
  • 2,813
  • 2
  • 21
  • 33
  • 1
    no you must never typecast a malloc in c , [see this](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc?rq=1) – Barath Ravikumar Mar 12 '13 at 12:19
  • But i used to typecast all of my program. It works without any error or crash, Why? – sujin Mar 12 '13 at 12:25
  • 1
    This is the [answer](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc?rq=1), to your question , if you have the time/patience , go and have a look there , but i have no time/patience to explain to you an answer , which is clearly explained in the link i sent. – Barath Ravikumar Mar 12 '13 at 12:30
  • thanks Mr.Barath Bushan. i cleared with the link which you sent. – sujin Mar 12 '13 at 12:41
  • 1
    no problem , just correct your answer about typecasting malloc – Barath Ravikumar Mar 12 '13 at 12:45