Vladimir Scofild
Vladimir Scofild

Reputation: 65

type casting in C

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.

Upvotes: 2

Views: 413

Answers (5)

paulm
paulm

Reputation: 5892

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

Upvotes: 6

eriknelson
eriknelson

Reputation: 839

(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).

Upvotes: 3

Konrad Rudolph
Konrad Rudolph

Reputation: 546153

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++.

Upvotes: 3

Mats Petersson
Mats Petersson

Reputation: 129524

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.

Upvotes: 10

Scott Jones
Scott Jones

Reputation: 2906

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.

Upvotes: 2

Related Questions