1

I've got a rather unusual question. I've seen two variants of passing arguments to malloc. Let's say we've got:

int *arr = (int *) malloc(sizex * sizeof(*arr));

Some people say that using sizeof(*arr) is bad and you should use sizeof(int) (in this example) instead. Could you explain what's the difference and what's better to use?

  • It's not really unusual: ["C" sizeof with a type or variable](http://stackoverflow.com/questions/373252/c-sizeof-with-a-type-or-variable) – zneak Apr 24 '14 at 18:50
  • If you ever need to change from `int` to, say, `float`, you wouldn't have to change much if you use first technique (`sizeof(*arr)`). Also, don't cast your `malloc`. – AntonH Apr 24 '14 at 18:50
  • Don't cast the return from `malloc()`, either. – Crowman Apr 24 '14 at 18:51
  • Just for fun, you can even write `int *arr = malloc(sizex * sizeof(arr[100]));` – Alex F Apr 24 '14 at 18:56
  • @pmg, is `sizeof (arr[0])` zero? – zneak Apr 24 '14 at 19:00
  • @pmg, `arr` is an pointer, not a type. `Sizeof (arr[100])` returns the size of the 100th element of `arr`, which is the same as `sizeof (arr[0])` or `sizeof (*arr)`. – zneak Apr 24 '14 at 19:57
  • Oops .. I misread your comments, my bad. Sorry. You're right – pmg Apr 24 '14 at 19:58

1 Answers1

1

There is no difference. Both allocate the same amount of memory -

int *arr = (int *) malloc(sizex * sizeof(*arr));
// equivalent to
int *arr = (int *) malloc(sizex * sizeof(int));

However, there are some things to note.

  1. You should not cast the result of malloc. It's not useful and can actually cause problems if you forget to include the header stdlib.h which contains its prototype. Please read this - Do I cast the result of malloc?

  2. I prefer the first version above because there's no repetition of the type information. Also, it's more maintainable in the sense that if you change the type, then you need to change it only once where as in the second case, you need to change it in two places.

It should be noted that sizeof needs parentheses for its operand only when it's a type. Therefore, it can be written more succinctly as

int *arr = malloc(sizex * sizeof *arr); 
// equivalent to
int *arr = malloc(sizex * sizeof(*arr));  // preferred way
Community
  • 1
  • 1
ajay
  • 9,402
  • 8
  • 44
  • 71
  • 1
    I like to think of parenthesis for `sizeof` as it being the type that needs parenthesis (like it was a cast). – pmg Apr 24 '14 at 18:58
  • @pmg, this is actually how it's described in the standard. – zneak Apr 24 '14 at 18:59
  • @pmg I think it's a personal choice. Doing away with a pair of parentheses makes the code a bit cleaner, I think but then it's me. – ajay Apr 24 '14 at 19:00
  • I don't like the redundant parenthesis. What I mean is that the parenthesis belong to the type, not to the operator. – pmg Apr 24 '14 at 19:01
  • @pmg true. now I think the parentheses might make the code more readable avoiding potential confusion. I'll include it but I need to be consistent with the style. – ajay Apr 24 '14 at 19:04