malloc and pointer casting

Discussion in 'C Programming' started by Mirko, Aug 31, 2005.

  1. Mirko

    Mirko Guest

    Hello, I'm new to this list and to Usenet in general,
    so please forgive (and advice) me, if I do something wrong.

    Anyway.

    I am a bit confused, because I always thought one
    _should_ explicitly cast the void* pointer returned by malloc.
    Now I read postings saying that this is dangerous.

    Could somebody please clearify this?

    Thanks
    Mirko
     
    Mirko, Aug 31, 2005
    #1
    1. Advertising

  2. Mirko wrote on 31/08/05 :
    > Hello, I'm new to this list and to Usenet in general,
    > so please forgive (and advice) me, if I do something wrong.
    >
    > I am a bit confused, because I always thought one
    > _should_ explicitly cast the void* pointer returned by malloc.


    You can, but it's just another waste of time. Please read the FAQ.

    --
    Emmanuel
    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
    The C-library: http://www.dinkumware.com/refxc.html

    I once asked an expert COBOL programmer, how to
    declare local variables in COBOL, the reply was:
    "what is a local variable?"
     
    Emmanuel Delahaye, Aug 31, 2005
    #2
    1. Advertising

  3. Mirko

    Mike Wahler Guest

    "Mirko" <> wrote in message
    news:...
    > Hello, I'm new to this list and to Usenet in general,
    > so please forgive (and advice) me, if I do something wrong.
    >
    > Anyway.
    >
    > I am a bit confused, because I always thought one
    > _should_ explicitly cast the void* pointer returned by malloc.


    Why did you think that? If you learned it from a book,
    please tell us the title and author so we can warn
    others about it.

    > Now I read postings saying that this is dangerous.
    >
    > Could somebody please clearify this?


    Casting the return value from 'malloc()' can mask errors
    (e.g. failure to provide its prototype via #including
    <stdlib.h>). In C89, calling a function without a
    prototype will cause a compiler to assume its return
    type is 'int'. So the returned pointer would be
    treated as type 'int', often corrupting its value.
    C99 makes this issue moot since it requires a prototype
    be in scope for any function called. However C99 is
    not in very widespread use yet, so this is still a
    very real issue.

    A 'void*' pointer can be implicitly converted to any
    other pointer type without any cast.

    IOW do things like so:

    #include <stdlib.h>

    int main()
    {
    int *p = malloc(sizeof *p * 100); /* 100 is arbitrary
    number for this example */

    if(p)
    {
    /* do something with 'p' */

    free(p);
    }
    else
    /* memory allocation failed, take corrective action */

    return 0;
    }

    Note that I also addressed another common mishandling of 'malloc()':
    failure to check its return value to see if it succeeded or not.


    comp.lang.c Frequently Asked Questions:
    http://www.eskimo.com/~scs/C-faq/faq.html

    -Mike
     
    Mike Wahler, Aug 31, 2005
    #3
  4. Mike Wahler wrote:
    >
    > "Mirko" <> wrote in message

    [... casting the return from malloc() ...]
    > > Now I read postings saying that this is dangerous.
    > >
    > > Could somebody please clearify this?

    >
    > Casting the return value from 'malloc()' can mask errors
    > (e.g. failure to provide its prototype via #including
    > <stdlib.h>). In C89, calling a function without a
    > prototype will cause a compiler to assume its return
    > type is 'int'. So the returned pointer would be
    > treated as type 'int', often corrupting its value.

    [...]

    To clarify this point...

    On some systems, sizeof(int) < sizeof(void*), meaning that, at best,
    the upper bits of the return value are lost, resulting in an invalid
    pointer. (For example, a 16-bit DOS system with 32-bit FAR pointers.)

    Worse, some systems return pointers differently than integers. For
    example, I've seen a CPU with two sets of registers -- one for data,
    one for addresses -- and the return value from functions was stored
    in the appropriate register. So, malloc() returns the pointer in the
    A0 register, while your code, thinking that malloc() returns an int,
    reads the D0 register for the value.

    Casting the return from malloc() would hide any warnings.


    --
    +-------------------------+--------------------+-----------------------------+
    | Kenneth J. Brody | www.hvcomputer.com | |
    | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Aug 31, 2005
    #4
  5. Mike Wahler wrote:

    >> I am a bit confused, because I always thought one
    >> _should_ explicitly cast the void* pointer returned by malloc.

    >
    > Why did you think that? If you learned it from a book,
    > please tell us the title and author so we can warn
    > others about it.


    Brian W. Kernighan, Dennis M. Ritchie: The C Programming Language (2nd
    Edition).


    Christian
     
    Christian Kandeler, Sep 1, 2005
    #5
  6. Christian Kandeler said:

    > Mike Wahler wrote:
    >
    >>> I am a bit confused, because I always thought one
    >>> _should_ explicitly cast the void* pointer returned by malloc.

    >>
    >> Why did you think that? If you learned it from a book,
    >> please tell us the title and author so we can warn
    >> others about it.

    >
    > Brian W. Kernighan, Dennis M. Ritchie: The C Programming Language (2nd
    > Edition).


    Fortunately for the faith of the faithful, K&R have dealt with this in their
    errata:

    http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html



    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29 July 1999
    http://www.cpax.org.uk
    Email rjh at the above domain
     
    Richard Heathfield, Sep 1, 2005
    #6
  7. Mirko

    John Bode Guest

    Mirko wrote:
    > Hello, I'm new to this list and to Usenet in general,
    > so please forgive (and advice) me, if I do something wrong.
    >
    > Anyway.
    >
    > I am a bit confused, because I always thought one
    > _should_ explicitly cast the void* pointer returned by malloc.
    > Now I read postings saying that this is dangerous.
    >
    > Could somebody please clearify this?
    >
    > Thanks
    > Mirko


    You've already gotten the correct answer, I just want to add a little
    historical context.

    Prior to C89, malloc() returned a char* instead of a void*, so a cast
    *was* required if the target wasn't a char*. So anyone who's been
    using C since before C89 is likely to still use the cast out of habit,
    even though it's no longer necessary.

    Also, anyone who goes back and forth between C++ and C is likely to use
    the cast, since C++ *doesn't* allow implicit conversions between void*
    and any other pointer type (but if you're writing C++, you shouldn't be
    using malloc() anyway).
     
    John Bode, Sep 1, 2005
    #7
  8. Mirko

    Mirko Guest

    Thanks to all who have answered, got exactly the information I was
    after.

    Perhaps one should add some lines to the FAQ, since it is not very
    informativ (presice) on that topic.

    Sorry, for this, to take so long, but I don't have an own internet
    access,
    so I can't read news regulary (in fact, it can take one or two weeks
    for
    me to respond).

    Thanks again

    Greetings
    Mikro
     
    Mirko, Sep 8, 2005
    #8
  9. Mirko

    Mirko Guest

    Mike Wahler wrote:
    > Mirko wrote:
    >> I am a bit confused, because I always thought one
    >> _should_ explicitly cast the void* pointer returned by malloc.


    > Why did you think that? If you learned it from a book,
    > please tell us the title and author so we can warn
    > others about it.

    Uhm, just too many... (mainly german, so called From-Beginner-to-Expert
    books).


    > C99 makes this issue moot since it requires a prototype
    > be in scope for any function called.

    Perhaps I'm mixing up different meanings of "scope", but if I
    understand
    you correctly, then it is forbidden in C99 to do something like this
    (IMHO bad style anyway):

    foo.c
    /* C99 would _require_ this; prior, we just get a warning. */
    /* int foo(void); */

    int main(void)
    {
    /* Wired, but C99 wouldn't complain, since prototype would be in
    scope. */
    /* int foo(void); */

    return foo(); /* error: no prototype in scope */
    }

    int foo(void)
    {
    return 0;
    }
     
    Mirko, Sep 8, 2005
    #9
  10. Mirko wrote:

    > I am a bit confused because I always thought [that]
    > one _should_ explicitly cast the void* pointer returned by malloc.


    That's correct.

    > Now I read postings saying that this is dangerous.


    FUD

    http://wombat.doc.ic.ac.uk/foldoc/

    > Could somebody please clarify this?


    C++ requires the explicit cast but C does not.
    Try to write code that will compile as either C or C++.

    > cat main.c

    #include <stdlib.h>

    int main(int argc, char* argv[]) {
    const
    size_t n = 100; // arbitrary size for this example
    int* p = (int*)malloc(n*sizeof(int));

    if (NULL == p) { // Memory allocation failed.
    // Take corrective action.
    }
    else {
    // Do something with 'p'.
    }

    free(p);
    return 0;
    }

    > gcc -x c -Wall -std=c99 -pedantic -o main main.c
    > gcc -x c++ -Wall -ansi -pedantic -o main main.c


    Don't write C code that C++ cannot accept.
    C++ will eventually replace C
    and you will either need to re-write your code or throw it away.
     
    E. Robert Tisdale, Sep 8, 2005
    #10
  11. Mirko

    John Bode Guest

    E. Robert Tisdale wrote:
    > Mirko wrote:
    >
    > > I am a bit confused because I always thought [that]
    > > one _should_ explicitly cast the void* pointer returned by malloc.

    >
    > That's correct.
    >


    In C++, yes. In K&R C, yes. In C89 and later, *no*.

    Put another way, it's just as correct as casting the result of "new".

    Snipping the rest.
     
    John Bode, Sep 8, 2005
    #11
  12. John Bode wrote:
    > E. Robert Tisdale wrote:
    >
    >>Mirko wrote:
    >>
    >>
    >>>I am a bit confused because I always thought [that]
    >>>one _should_ explicitly cast the void* pointer returned by malloc.

    >>
    >>That's correct.
    >>

    >
    > In C++, yes. In K&R C, yes. In C89 and later, *no*.


    BZZT! In K&R C there is no such thing as a void*, so it cannot be true
    that in K&R C one should explicitly cast the void* pointer returned by
    malloc. Casting the char* returned by a K&R C library's malloc would be
    a good idea, though.
     
    Martin Ambuhl, Sep 8, 2005
    #12
  13. Mirko

    John Bode Guest

    Martin Ambuhl wrote:
    > John Bode wrote:
    > > E. Robert Tisdale wrote:
    > >
    > >>Mirko wrote:
    > >>
    > >>
    > >>>I am a bit confused because I always thought [that]
    > >>>one _should_ explicitly cast the void* pointer returned by malloc.
    > >>
    > >>That's correct.
    > >>

    > >
    > > In C++, yes. In K&R C, yes. In C89 and later, *no*.

    >
    > BZZT! In K&R C there is no such thing as a void*, so it cannot be true
    > that in K&R C one should explicitly cast the void* pointer returned by
    > malloc. Casting the char* returned by a K&R C library's malloc would be
    > a good idea, though.


    Brain fart -- I misread "the void* pointer returned by malloc" as "the
    value returned by malloc".

    It's been a long week already, and this just made it longer.
     
    John Bode, Sep 8, 2005
    #13
  14. "E. Robert Tisdale" <> writes:
    > Mirko wrote:
    >
    >> I am a bit confused because I always thought [that]
    >> one _should_ explicitly cast the void* pointer returned by malloc.

    >
    > That's correct.


    No, it isn't.

    >> Now I read postings saying that this is dangerous.

    >
    > FUD
    >
    > http://wombat.doc.ic.ac.uk/foldoc/
    >
    >> Could somebody please clarify this?

    >
    > C++ requires the explicit cast but C does not.
    > Try to write code that will compile as either C or C++.


    Write in C, or write in C++. A very few developers have a legitimate
    need to write code that's compatible with both. If you have such a
    need, chances are you're P.J. Plauger, and you don't need advice from
    me.

    > Don't write C code that C++ cannot accept.
    > C++ will eventually replace C
    > and you will either need to re-write your code or throw it away.


    There is no reason to believe that C++ will replace C.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 8, 2005
    #14
  15. On 8 Sep 2005 06:26:39 -0700, "Mirko" <> wrote:

    > Mike Wahler wrote:

    <snip>
    > > C99 makes this issue moot since it requires a prototype
    > > be in scope for any function called.


    Actually C99 requires a declaration but not necessarily a prototype. A
    prototype in C is a specific kind of declaration or definition, that
    specifies the types (at least) of the parameters in the parentheses
    indicating that it is a function, although many people misuse the term
    to mean any declaration of a function, especially "published".

    > Perhaps I'm mixing up different meanings of "scope", but if I
    > understand
    > you correctly, then it is forbidden in C99 to do something like this
    > (IMHO bad style anyway):
    >
    > foo.c
    > /* C99 would _require_ this; prior, we just get a warning. */
    > /* int foo(void); */
    >
    > int main(void)
    > {
    > /* Wired, but C99 wouldn't complain, since prototype would be in
    > scope. */
    > /* int foo(void); */
    >
    > return foo(); /* error: no prototype in scope */
    > }

    <snip>

    Sort of. Let's review:

    int foo (void); is a prototype declaration of a function with no
    arguments. int foo (); is a declaration but not a prototype.
    Prototypes are better because they allow more error checking by the
    compiler and appropriate automatic conversion of arguments (for
    functions that take arguments, of course) but they are not required,
    not even in C99. (They are, effectively, in C++.)

    Before C99, you can declare a function at file scope a.k.a. top level
    and it applies to the whole rest of the file (translation unit) unless
    shadowed, or you can declare it within a function body or other block
    and it applies only within that block. Or, if you call a named
    function directly and it you haven't declared it either place, the
    compiler assumes an implicit declaration like int foo() i.e. returning
    int and accepting unspecified fixed default-promoted arguments.

    It is considered poor style to put function declarations locally in a
    function/block, because that's not where people expect to see them or
    find them when looking, and it allows the coder to accidentally or
    intentionally have inconsistent declarations e.g. char * foo (int) in
    one place and void foo (int, char *) in another, which is wrong and
    often badly wrong, without the compiler detecting. But it is legal.

    C99 removes the last option, implicit declaration. You can declare,
    prototype or not, at file scope or local scope. But you must declare.

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Sep 14, 2005
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ken
    Replies:
    3
    Views:
    2,575
    Rolf Magnus
    Nov 8, 2003
  2. __frank__

    Linked list: casting a malloc pointer

    __frank__, Oct 11, 2005, in forum: C Programming
    Replies:
    3
    Views:
    452
    Kenneth Brody
    Oct 11, 2005
  3. Abhishek

    Casting a file pointer to char pointer

    Abhishek, Mar 21, 2006, in forum: C Programming
    Replies:
    9
    Views:
    668
    santosh
    Mar 22, 2006
  4. SRR
    Replies:
    41
    Views:
    1,327
    Yevgen Muntyan
    Mar 11, 2007
  5. Replies:
    11
    Views:
    1,427
    James Kanze
    Jun 7, 2007
Loading...

Share This Page