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

and,

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

could anybody explain me what occurs internally and what the difference between using (int*) and (int)? Thanks.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
  • 15
    Both of these things are very wrong, and you should never do either. – Jon Apr 30 '13 at 21:38
  • 5
    Which is it: C or C++? The answer will be fundamentally different depending on this. – Konrad Rudolph Apr 30 '13 at 21:40
  • 1
    @Jon Since the question is tagged C++ also, the cast to `int *` may be necessary. But then again, there's very little reason to use `malloc` instead of `new` in C++. – Praetorian Apr 30 '13 at 21:41
  • 1
    @Praetorian: The main problem though is the conversion to `int`. – Jon Apr 30 '13 at 21:43
  • You are assigning incompatible types.The compiler warning should be enough indication.You are assigning a pointer `int*` to an integer variable `int p`.In the second statement you are casting a pointer to an integer value.This may suppress warnings,but the first statement is wrong. – Rüppell's Vulture Apr 30 '13 at 21:48
  • I think this is properly called, simply, *casting*. *Type-casting* is when you see the same actor in the same kind of role in many different theatrical or cinematic performances. – luser droog May 01 '13 at 03:32

5 Answers5

10

Both of your examples are "bad".

The first one is incorrect, as it tries to assign a pointer to an integer, and thus should at the very least give a warning, more likely an error. And if the machine is 64-bit and you are compiling it as 64-bit code, the pointer may not fit in the integer [same applies to a 16-bit int on a 32-bit machine, but that's not very common these days].

The second example will most likely compile, but it's still assigning an integer with the value of a pointer, which is pretty much pointless (and it may not fit, as pointers are bigger than int).

In "C", you should not use casts to assign the value returned by malloc - it is wrong, and can lead to problems.

In "C++", you should not use malloc, use new instead.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
6

Since this is tagged C++ I'll take the C++ angle to the answer:

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

Both of these are wrong, malloc returns a pointer to some memory. I think what you actually wanted was to allocate an int on the heap, thus your return value is int*.

Depending on 32 or 64bit arch this code will break because you are going to assign 64bits of data to 32bits of storage.

The correct way in C is:

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

Which is saying, allocate enough space for the type int, and store a pointer to this allocated space. No cast is required in C.

In C++ it would look like this if you used malloc:

int* p = static_cast<int*>(malloc(sizeof(int)));

Now the cast IS required, however you can avoid this by using operator new:

int* p = new int; // much cleaner!

Note that operator new will throw std::bad_alloc on failure rather than returning nullptr/0/NULL.

If you don't want it to throw but want the cleaner syntax you can use:

int* p = new (std::nothrow) int;

Or even better still, either don't allocate on the heap unless really needed, or use a smart pointer so you don't have to worry about calling operator delete or free():

std::unique_ptr<int> p(new int); // when p leaves scope, the memory is deleted
paulm
  • 5,629
  • 7
  • 47
  • 70
3

(int *) is a cast to a pointer to an integer
(int) is a cast to an integer

They are quite different concepts in their own right. See this tutorial for more on pointers and how/when you should use them. They are a fundamental to C programming (and I would argue it's important to understand indirection as a concept as it pervades programming in general).

eriknelson
  • 849
  • 2
  • 11
  • 21
3

You are allocating a pointer to int – i.e. int* yet you are trying to assign the result to an int. That does not work.

In C, you do not need, and should not use, a cast:

int *pi = malloc(sizeof(int));

In C++, the cast is required but the (…) cast syntax (called “C-style cast”) is discouraged, as is the usage of malloc, for that matter. So syntactically correct C++ would be

int* pi = static_cast<int*>(malloc(sizeof(int)));

However, good code would be either (a) avoiding the pointer allocation entirely, (b) using a ready-made class that handles the allocation, such as boost::optional<int>, or, as a last resort, using a smart pointer (e.g. std::unique_ptr<int>). If, for unfathomable reasons, you actually want to manually allocate and handle memory in C++, use either the new operator or an allocator class (such as std::allocator). Use malloc in C++ code only if you are passing memory to a C API which explicitly requires you to allocate memory for its arguments via malloc. This is the only valid use of malloc in C++.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 2
    sizeof(pi) is broken, it should be sizeof(int) since sizeof(pi) becomes sizeof(int*) which will change depending on 32 or 64bit – paulm Apr 30 '13 at 21:45
  • @paulm Right you are; I actually meant `*pi` but that becomes cryptic for beginners. – Konrad Rudolph Apr 30 '13 at 21:46
2

The assignment should be:

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

malloc returns void * (always a pointer), which you would then want to cast to the appropriate pointer type, such as int *. It's also important to free() the allocated memory when you're done using it, to prevent a memory leak. I assume your example is academic, as there are few cases where you'd want/need to allocate an int on the heap.

Scott Jones
  • 2,880
  • 13
  • 19