Whenever I see malloc
in someone else's code, it typically uses sizeof(short)
or sizeof(double)
etc. to help define the size of memory to be allocated. Why do they not just replace those expressions with 2
or 8
, in those two examples?

- 203,559
- 14
- 181
- 302

- 22,823
- 57
- 147
- 247
-
14Because the size of a type can change depending on the platform the code is running on. The standard only guarantees minimum sizes. – NathanOliver Mar 19 '15 at 17:55
-
see: [Why does sizeof(int) vary across different operating systems?](http://stackoverflow.com/q/14256695/1708801) there is probably a better duplicate to be found. – Shafik Yaghmour Mar 19 '15 at 17:55
-
8`sizeof(double) == 64` that's news to me, are you sure about that? – jrok Mar 19 '15 at 17:55
-
8Why are you using `malloc` in C++ code? – Ed Heal Mar 19 '15 at 17:56
-
What's the c++ version of `malloc`? – Karnivaurus Mar 19 '15 at 17:58
-
3@Karnivaurus `new`, `new[]` and respectively `delete` and `delete[]` – Emil Laine Mar 19 '15 at 18:00
3 Answers
It makes the code easier to port.
In general there are compiler options which allow you to say how data is to be alligned in a struct. The size of a double may vary between platforms. By consistantly using the data type, you reduce the occurance of some types of size mismatch errors.
I think it is a better practice to use the variable name instead of the data type for the size of piece.
float Pi = 3.14f;
float *pieArray = (float *) malloc(sizeof (Pi) * 1000);
Personally I would prefer this method.
typedef float Pi;
Pi *piArray = new Pi[1000];
// use it
delete[] piArray;
new/delete should be preferred over malloc/free in most cases.

- 28,120
- 21
- 85
- 141
-
1Note that `sizeof` is an operator, not a function, and the parentheses are only required if the operand is a type name; `sizeof Pi` will work just as well. – John Bode Mar 19 '15 at 18:14
-
2Yet, in this case, if you change the type of `Pi` you still have a problem. You're better off using `sizeof *pieArray`. Yes, you could still mismatch `Pi`, but from a perspective of performing operations on the array, you're in better shape. Also, don't case the return value of `malloc` in C – Ed S. Mar 19 '15 at 18:16
-
-
@ed. Personally i would use new syntax instead of malloc, and typedef Pi as a data type, then use the data type rather than float in the second statement. Never the less, the op is using malloc, so I did too. – EvilTeach Mar 19 '15 at 18:17
-
1Well, yes, the OP doesn't seem to understand the differences between C and C++. We should assume C here. My point about using the type of the array still stands. There's no good reason not to. – Ed S. Mar 19 '15 at 18:18
-
To further nitpick... if we're going to add a C++ example, use `std::vector` and be done with it – Ed S. Mar 19 '15 at 18:30
-
Another point is maintenance. If the contents of the structure change, then all the hard coded allocation quantities must be reviewed. Without hard coded values, this review is not necessary. – Thomas Matthews Mar 19 '15 at 18:34
-
-
using the name instead of type is a problem if the compiler don't know the length. You then get the length of the pointer to the variable. – fhtuft Mar 19 '15 at 18:38
-
1I'm not convinced that clearing up obvious confusion is something to be avoided, but he'll have to figure it out eventually. You also fail to explain *why* `new/delete` is preferred in C++. – Ed S. Mar 19 '15 at 18:38
The most portable and maintainable way to write a malloc
call in C is:
T *p = malloc( N * sizeof *p );
or
T *p;
...
p = malloc( N * sizeof *p );
where T
is any arbitrary type and N
is the number of objects of that type you want to allocate. Type sizes are not uniform across platforms, and the respective language standards only mandate minimum ranges of values that non-char
types must be able to represent. For example, an int
must represent at least the range [-32767...32767]
, meaning it must be at least 16 bits wide, although it may be (and often is) wider. For another example, struct
types may have different amounts of padding between members depending on the platform's alignment requirements, so a struct foo
type may take up 24 bytes on one platform and 32 on another.
The expression *p
has type T
, so sizeof *p
gives the same result as sizeof (T)
, which is the number of bytes required to store an object of type T
. This will always give you the right number of bytes to store your object (or sequence of objects), regardless of platform, and if you ever change T
(from int
to long
, for example), you don't have to go back and change the arguments to the malloc
call.
Note that you shouldn't use malloc
or calloc
in C++ code; you should use a standard container like a vector
or map
that handles all the memory management for you. If for some reason a standard container doesn't meet your needs, use the new
operator to allocate a single object of type T
and new []
to allocate an array of objects.

- 119,563
- 19
- 122
- 198
Neither the size of a double or a short is fixed by the c++ standard. Note that for a double, it doesn't even have to be an IEEE754 floating point type. In this respect c++ differs from Java. So it would be a poor idea to hardcode the size.
And use new
/ new[]
and delete
/ delete[]
in C++.

- 231,907
- 34
- 361
- 483
-
1Where does it say that? Under [expr.sizeof] it only defines size of `char`, and `signed char` and `unsigned char` and says the size of other fundamental types are implementation-defined. – Mar 19 '15 at 18:02
-
2"A double is fixed at 64 bits by the standard so has a sizeof 8" – um, I don't think either of that is true. Floating-point types have *minimal* precision and range requirements, but it's not fixed. Also, a 64-bit number can have any `sizeof` less than or equal to 8 – since `CHAR_BIT` is defined to be *at least* 8, but it could be more. (also, if we consider the ability to add padding bits, then the result of sizeof could vary in an even wider range.) – The Paramagnetic Croissant Mar 19 '15 at 18:22
-