13

Please note this question is not about malloc in C or malloc vs new/smart pointers in C++.

If I use malloc in C++, what kind of cast should I use? The following all work.

int *a = (int *)malloc(sizeof (int));
int *b = static_cast<int *>(malloc(sizeof (int)));
int *c = reinterpret_cast<int *>(malloc(sizeof (int)));

Live example: http://ideone.com/lzfxcm

I prefer to use C++ style casts in my code as much as possible and I want to adopt safe coding habits. Please advise with this in mind.

Thank you.

Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
  • for malloc, a C style cast is no less safe than reintprerpt_cast. – tenfour Sep 25 '13 at 12:28
  • 4
    to be safe you should use new and not malloc – AndersK Sep 25 '13 at 12:29
  • 3
    @claptrap I specifically stated this question is NOT about malloc vs new. Sometimes malloc is used in C++. It happens. – Neil Kirk Sep 25 '13 at 12:30
  • `(int *)` does the job right, less to type, easy to read. – dmitri Sep 25 '13 at 12:32
  • 3
    @NeilKirk: "Sometimes malloc is used in C++" When, exactly? Give at least one scenario. – SigTerm Sep 25 '13 at 12:46
  • @NeilKirk sigterm is right, I can't think of any situation where one would prefer malloc over new in C++. Even if it doesn't matter at all, I would still stick to conventions and use new. – Kevin Sep 25 '13 at 12:48
  • @SigTerm: When you're implementing a custom allocator. Of course, you won't be casting the result in that case; I can't imagine any situation where this question would be relevent. – Mike Seymour Sep 25 '13 at 12:49
  • @MikeSeymour: Unless I'm missing something, even with custom allocator you'll either use your own memory functions (that are not malloc), or you can allocate memory block via `new char*`. So even in this case it isn't exaclty required. – SigTerm Sep 25 '13 at 12:52
  • @SigTerm: If you're replacing the global `operator new`, then you can't use `new` in there; that will recursively call your operator. So you'll need something else to give you raw memory - such as `malloc`. (But we're getting very off-topic here). – Mike Seymour Sep 25 '13 at 13:04
  • @MikeSeymour: "But we're getting very off-topic here" Maybe. My point was that even when you're overriding global operator new and/or write allocators, there's a very good chance that you won't be using malloc directly. So this scenario is very rare. – SigTerm Sep 25 '13 at 13:21
  • @SigTerm: When you're calling C functions requiring/returning an allocated block of memory to write to. We (usually) have no control over the libraries we use. Rather than use new (and let the library use free()) or use delete (while the library uses malloc()), it's simpler to just use malloc/free. – Lelanthran May 19 '15 at 07:11

4 Answers4

13

Since malloc returns a pointer to void, there is no reason to use a C++ - style cast on the pointer: you get a chunk of raw memory, with no structure behind it, so the only thing your can tell the compiler by adding a cast is that you plan to use this memory for data of a particular kind. Compiler must agree with you on that, because it has no additional information to double-check your decision. Neither static_cast<T> nor the reinterpret_cast<T> offer a particular advantage over the C-style cast, and the C-style cast is shorter.

From the personal perspective, I looked at a lot of C++ code, but I've never seen a C++ - style cast used with malloc, only the C-style.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
13

I would prefer to use static_cast, as what you are doing is converting a void* to a pointer to some other object type, which is well defined in C++.

C-style cast should not be used in C++, as the compiler will perform no type checking whatsoever - by using a C-style cast, you lose all type safety. The idea is to restrict your casts to only what is needed and no more.

reinterpret_cast has a different purpose - to reinterpret the bits of an object as some other type. void is not an object, so this clearly doesn't apply to void*/malloc.

johnny
  • 4,024
  • 2
  • 24
  • 38
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • (+1) I was about to post a similar answer :-) This is a [relevant link](http://stackoverflow.com/a/7970036/2633423) on SO. – LorenzoDonati4Ukraine-OnStrike Sep 25 '13 at 12:38
  • 1
    `C-style cast should not be used in C++` There should be better justifications than that, or there are none? – dmitri Sep 25 '13 at 12:39
  • 2
    @dmitri: I've updated my answer. Besides, I am a C++ purist. – Jesse Good Sep 25 '13 at 12:43
  • Personal preferences are OK but a forum like this is more about technical merits, don't you think? `malloc` returns `void*`, that doesn't carry type information so compiler can't do much of type checking here. Am I missing something? – dmitri Sep 25 '13 at 12:49
  • @dmitri: Yes, the compiler cannot do much type checking in this case, but **in general** you should use the strictest cast possible, which means `static_cast` would be preferred in this situation. – Jesse Good Sep 25 '13 at 12:59
2

Sticking to the principle to always use the "least-violent" cast, I would recommend static_cast.

However, even better would be a wrapper function like

template <typename T>
T* mnew(std::size_t count = 1)
{
    return static_cast<T*>(malloc(sizeof(T) * count));
}
Oberon
  • 3,219
  • 15
  • 30
  • Why would you use this function, and not just `operator new`? – tenfour Sep 25 '13 at 12:38
  • 5
    Because it (1) returns `NULL` instead of calling the new-handler and/or throwing `std::bad_alloc` in case of errors, (2) the returned pointer must be freed with `free()` instead of `delete[]` or `delete` and (3) it does not call any constructors. – Oberon Sep 25 '13 at 12:40
0

malloc returns void* pointer which you can cast it to any desired pointer using C style casts but C++ introduced 4 new cast operator to overcome one disadvantage assoicated with C style casts and that is they can-not be easily detected using IDE or any other tools like grep.

Conside your example

int *a = (int *)malloc(sizeof (int));
int *b = static_cast<int *>(malloc(sizeof (int)));
int *c = reinterpret_cast<int *>(malloc(sizeof (int)));

Here you can easily search for all instances of static_cast or reinterpret_cast but had it been c style cast then you got no other way but to simply look or dig into code and spent sleepless nights. Believe me casting bugs are very hard and they undermined strong typing guarantee offered by the C and C++ style languages. But their are some genuine cases where in such cast is needed.

Hence C++ allows C style casting but it intoduce reinterpret_cast operator which does nothing but C style cast operation.

http://www.stroustrup.com/bs_faq2.html#void-ptr

anonymous
  • 1,920
  • 2
  • 20
  • 30