Thread: Should I cast return value of malloc?

  1. #1
    Linux is where it's at movl0x1's Avatar
    Join Date
    May 2007
    Posts
    72

    Should I cast return value of malloc?

    Hi. Alot of people say you shouldn't cast the returned pointer from malloc(),
    but just make sure it's not NULL. Isn't malloc supposed to return type void?

    Also, if you don't cast how will the compiler know the pointer increments
    by char, int, etc?

    thanks
    Remember that all that code you write turns into this:

    0100100100110010010011100100111001001
    0010100100100001001111100010010010010 ....

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Oh man.... Not another debate on this. :'(

    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    http://cboard.cprogramming.com/showthread.php?t=25799

    If you are likely to port your code to C++, you should cast (or just write it in C++ originally to begin with, using new instead of malloc()).

    I like to cast because of that reason, plus I feel it makes the memory allocation clearer.

    The other school of thought is that it clutters your code and forces you to recast if you change the variable type. In addition, if you forget to include stdlib.h, and int and void * are not the same size, then you could cause a hard-to-find bug, although this argument does not apply to C99 (and shouldn't apply to C89 if you turn your compiler warnings up high enough).

    In reality, malloc() returns void *, which is a void pointer. A void * can point to almost any other pointer data type. This is how you can receive a block of memory to any data type.

    So no, you don't need to cast. Should you cast? As the faq concludes:

    No, that is the preferred method. However, you should use whichever you like provided you are aware of the issues.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    > If you are likely to port your code to C++, you should cast (or just write it in C++ originally to begin with, using new instead of malloc()).

    Although in C++ it's safer to use static_cast instead of the C-style cast (to make it easier to find the really dangerous casts), in which case it's not much less work to convert than just adding the static_cast from scratch.

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    In C++ you will use new, or vector, or std::string...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by robatino View Post
    > If you are likely to port your code to C++, you should cast (or just write it in C++ originally to begin with, using new instead of malloc()).

    Although in C++ it's safer to use static_cast instead of the C-style cast (to make it easier to find the really dangerous casts), in which case it's not much less work to convert than just adding the static_cast from scratch.
    Macgyver's point was that, if you are using C++, it is better to use operator new and not use malloc() at all (or a standard container, which uses operator new behind the scenes).

    With some very old C compilers (predating the 1989 C standard by at least a decade or so) a cast was necessary. In those days, C did not have a void keyword, and malloc() returned a pointer to char. Very few of us will have to use such antique compilers (even the machines and operating systems they ran on are hard to find).

    With 1989 standard C, a cast is not necessary, and it considered bad style to cast the return from malloc(). The unincluded stdlib.h header is one justification cited for that (although, in practice, as MacGyver said, that argument does not apply to C99 and tweaking a lot of good quality C89 compilers to maximum warning levels would pick up such concerns -- which suggests to me the argument was always rather specious).

    One practical issue is that a lot of C89 compilers were (and often are) actually C++ compilers (those before 1998 were implemented in approximate compliance with draft C++ standards of the time). Some very old drafts of the C++ standard (to 1990 or so, roughly predating the ARM) did not support keywords like static_cast, and the only way to coerce some early C++ compilers into accepting a malloc() call was therefore to use a vanilla C cast on malloc()'s return value.

    Another practical issue is porting C89 compliant code (assuming it was developed with a C compiler that was not a C++ compiler) to C++. A cast of malloc() is a quick and easy way to shut up a moaning C++ compiler. It therefore was, and often remains, a simple way for a C programmer to allow for potential compilation of their code with a C++ compiler. This approach is considered bad style in C but is an approach used practically by a lot of real world programmers who practically need to keep a foot in both C and C++ camps.
    Last edited by grumpy; 05-30-2007 at 06:35 AM.

  6. #6
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    So would it be better to 'define' your own, depending on whether its being compiled as C or C++?

    Such as,
    Code:
    #ifdef CPP /* or whatever it is */
        /* dunno */
        #define myFree(ptr) delete ptr /* dunno */
    #else
        #define myAlloc(type, size) malloc(size)
        #define myFree(ptr) free(ptr)
    #endif
    Or is there a better way to go?

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Why do you want to write in C code that is compiled by C++ compiler?
    Why not to write code in C++ that can be compiled as java-code?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by zacs7 View Post
    So would it be better to 'define' your own, depending on whether its being compiled as C or C++?

    Such as,
    Code:
    #ifdef CPP /* or whatever it is */
        /* dunno */
        #define myFree(ptr) delete ptr /* dunno */
    #else
        #define myAlloc(type, size) malloc(size)
        #define myFree(ptr) free(ptr)
    #endif
    Or is there a better way to go?
    delete requires the []'s for a block of memory. That would make your custom free() need an extra parameter to tell whether it was a block or just one element.

    Quote Originally Posted by vart View Post
    Why do you want to write in C code that is compiled by C++ compiler?
    Why not to write code in C++ that can be compiled as java-code?
    It's more likely you will go from C to C++ than C to Java, isn't it? Also, there is nothing you can do to make your C code Java-compliant, but you can make your C code C++ compliant for the most part.

    Many people seem to think that code written in C should compile as C++. That presents a problem if you write C code that does end up needing to be ported to C++.

  9. #9
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    So defining your own custom free()'s and malloc()'s isn't the way to go?

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    > Macgyver's point was that, if you are using C++, it is better to use operator new and not use malloc() at all (or a standard container, which uses operator new behind the scenes).

    If one is porting C code, and it uses realloc() (with no direct C++ analogue), then it depends on how much effort one is willing to spend on the port. Adding either a C-style cast or a static_cast is simple and mechanical. In C++, using vectors and the swap trick (to trim capacity) is preferable to using realloc(), but requires a fair amount of redesign (I'm a long-time C coder just learning C++ and recently had to do this to some of my early C++ code using dynamic arrays, so I know firsthand).

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Casting malloc is only the beginning of your problems when trying to convert C to C++
    http://david.tribble.com/text/cdiffs.htm

    The problem with writing polyglot code is that you end up using the worst features of both languages you're trying to be compatible with.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Many people seem to think that code written in C should compile as C++. That presents a problem if you write C code that does end up needing to be ported to C++.
    I'm lucky guy - never worked with any of these many people...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by movl0x1 View Post
    Hi. Alot of people say you shouldn't cast the returned pointer from malloc(),
    but just make sure it's not NULL. Isn't malloc supposed to return type void?
    It returns void *, not void. Totally different thing.

    Also, if you don't cast how will the compiler know the pointer increments
    by char, int, etc?
    The pointer is automatically CONVERTED to the type of the variable on the left hand side of the assignment. You COULD cast it, but the reason void * exists is so that you don't HAVE to. You're right -- the compiler doesn't know the size of the type until the pointer is converted to the appropriate type. The point is, you do not have to do an explicit cast to perform the conversion. The following is enough:

    Code:
    some_structure *ptr;
    /* Compiler AUTOMATICALLY converts the void * into a some_structure pointer */
    ptr = malloc(sizeof(*ptr));
    There are two main reasons not to cast.

    1. The compiler does it for you. This is the WHOLE POINT of void *. By casting you are saying you don't trust the C language.

    2. If you cast explicitly, it can hide the fact that you have forgotten to include stdlib.h. Without the header file, a call to malloc() is undefined behavior. But the explicit cast shuts up the warning you would otherwise get. So casting malloc() == bad.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. New string functions
    By Elysia in forum C Programming
    Replies: 11
    Last Post: 03-28-2009, 05:03 AM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  3. need help program crashing
    By tunerfreak in forum C++ Programming
    Replies: 14
    Last Post: 05-22-2006, 11:29 AM
  4. Linking OpenGL in Dev-C++
    By linkofazeroth in forum Game Programming
    Replies: 4
    Last Post: 09-13-2005, 10:17 AM
  5. opengl help
    By heat511 in forum Game Programming
    Replies: 4
    Last Post: 04-05-2004, 01:08 AM