25

I acknowledge that all three of these have a different meaning. But, I don't understand on what particular instances would each of these apply. Can anyone share an example for each of these? Thank you.

       malloc(sizeof(int))
       malloc(sizeof(int *))
(int *)malloc(sizeof(int))
Ward Segers
  • 519
  • 5
  • 17
rajagrawal
  • 622
  • 4
  • 14
  • 26

2 Answers2

52

malloc(sizeof(int)) means you are allocating space off the heap to store an int. You are reserving as many bytes as an int requires. This returns a value you should cast to int *. (A pointer to an int.) As some have noted, typical practice in C is to let implicit casting take care of this.

malloc(sizeof(int*)) means you are allocating space off the heap to store a pointer to an int. You are reserving as many bytes as a pointer requires. This returns a value you should cast to an int **. (A pointer to a pointer to an int.)

(int *)malloc(sizeof(int)) is exactly the same as the first call, but with the the result explicitly casted to a pointer to an int.

Note that on many architectures, an int is the same size as a pointer, so these will seem (incorrectly) to be all the same thing. In other words, you can accidentally do the wrong thing and have the resulting code still work.

Gort the Robot
  • 2,329
  • 16
  • 21
  • 2
    +1 for the last paragraph - however in my experience, Many C programmers 'intentionally' do the wrong thing and it works, so they keep doing it..... – mattnz Mar 05 '13 at 08:32
  • 5
    RE first paragraph: In C, many people argue that you shouldn't cast it (there's an implicit conversion from `void *` to any pointer type in C, so it works). See http://stackoverflow.com/q/605845/395760 –  Mar 05 '13 at 14:31
  • @StevenBurnap I suspect you actually mean "use" where you say "cast". There's an implicit conversion from void* to any other data pointer type (I don't recall if the standard says you can safely cast a void* to a function pointer, though). – Vatine Mar 20 '13 at 15:09
9

The syntax pattern that is most foolproof is:

 int *p;
 p = malloc (cnt * sizeof *p);

This syntax will not force you to change the code if the type (and or size...) of *p changes, eg in

 struct mysstruct *q;
 q = malloc (cnt * sizeof *q);

Which will avoid problems like

struct mysstruct *z;
z = malloc (cnt * sizeof(struct hisstruct)); // Auch!

, plus: the sizeof expr form is also shorter.


UPDATE: to demonstrate the correctness of p = malloc(CNT * sizeof *p) this test program:

#include <stdio.h>
#include <stdlib.h>

struct mystruct {
        int i;
        char s[14];
        };
int main(void)
{
struct mystruct *p;
size_t siz;

siz = sizeof p;
printf("Sizeof p := %zu\n", siz);

siz = sizeof *p;
printf("Sizeof *p := %zu\n", siz);

printf("Allocating %zu (%u structs, each of size %zu) bytes to be assigned to p...\n"
        , 10u * sizeof *p
        , 10u, sizeof *p
        );
p = malloc(10 * sizeof *p);

return 0;
}

Which outputs here:

Sizeof p := 8
Sizeof *p := 20
Allocating 200 (10 structs, each of size 20) bytes to be assigned to p...
wildplasser
  • 43,142
  • 8
  • 66
  • 109
  • The pattern is not `malloc (cnt * sizeof *p)`, but as the accepted answer properly noted, `sizeof p`. Same for q/*q. Otherwise you need `int **p` to properly hold the result. – EntangledLoops Jun 02 '15 at 20:00
  • 1
    I dont understand your question. `Type *t; t = malloc(CNT * sizeof *t);` is **always** right, the other variants are *sometimes* right. – wildplasser Jun 02 '15 at 21:32
  • It wasn't a question and *no*, that is not always right. You are assuming that the `sizeof *t` = `sizeof t`, which is not necessarily true. Your line should correctly read: `Type *t; t = malloc(CNT * sizeof t);` – EntangledLoops Jun 03 '15 at 14:06
  • 1
    @snd You are wrong; I added a snippet to my answer. – wildplasser Jun 03 '15 at 14:28
  • Your snippet is incorrect and also non-standard `sizeof` syntax. You used `malloc` improperly. It should be: `p = malloc(10 * sizeof p);`. You allocated too much memory for a pointer to `p`. This snippet would not function if the sizes of `p` and `*p` were reversed. – EntangledLoops Jun 03 '15 at 18:30
  • 2
    I don't *intend* to allocate memory for a pointer (that would be useless) or for 10 pointers, I intend to allocate memory for 10 structs. And it is **not** "non-standard syntax" (whatever that is) – wildplasser Jun 03 '15 at 18:36
  • Ahh I see what you're doing now---but why wouldn't you just make it clear and use the actual struct? Like `10 * sizeof mystruct` instead of `*p`? Can't you see how that's misleading? – EntangledLoops Jun 03 '15 at 18:51
  • 2
    I explained that in the third part (the one with the `// Auch!`) The point I try to make is that `malloc(10 * sizeof(struct mystruct))` (BTW: this syntax **needs** the parentheses) is more error prone (because `struct mystruct` should correspond to the *actual* type you want) If you make a change: you'll need to change them both. – wildplasser Jun 03 '15 at 18:58