Question regarding malloc casing

Discussion in 'C Programming' started by somenath, Dec 2, 2007.

  1. somenath

    somenath Guest

    Hi All,

    I have one question regarding return value cast of malloc.

    I learned that we should not cast the return value of malloc because
    it is bug hider.
    But my question is as mentioned bellow .

    Lets say I have not included stdlib.h in my program still I am using
    malloc so compiler will throw warring because with out prototype
    compiler assumes that function is declared as extern int
    malloc() .Suppose I ignore that warning and did not cast the return
    value
    Now during linking time my code will be linked to exact
    implementation of malloc which returns void * . So in this case will
    it be a problem?

    Regards,
    Somenath
    somenath, Dec 2, 2007
    #1
    1. Advertising

  2. somenath <> wrote:
    > Hi All,
    >
    > I have one question regarding return value cast of malloc.
    >
    > I learned that we should not cast the return value of malloc
    > because it is bug hider.
    > But my question is as mentioned bellow .
    >
    > Lets say I have not included stdlib.h in my program still I
    > am using malloc so compiler will throw warring because with
    > out prototype compiler assumes that function is declared
    > as extern int malloc().


    If you ignore the bug, the bug remains. Even without an
    explanation, I can't this as ever being a Good Thing (TM).

    > Suppose I ignore that warning and did not cast the return
    > value
    > Now during linking time my code will be linked to exact
    > implementation of malloc which returns void * . So in this
    > case will it be a problem?


    Yes.

    On a typical motorola 68k implementaion, the library will
    return the pointer in A0, whereas your code will expect
    it in D0.

    On a stack based implementation where void * is 64 bits
    and int is 32-bits, you may find the library function will
    clean up too much stack.

    Fact is, failing to declare a prototype is seen as such
    a weakness in the C language that many people prefer to
    tell their compilers to make it an error to call an
    unprototyped named function, even though it breaks the
    conformance of the compiler. Some even go so far as use
    C++ instead of C.

    --
    Peter
    Peter Nilsson, Dec 2, 2007
    #2
    1. Advertising

  3. somenath

    somenath Guest

    On Dec 2, 10:02 am, Peter Nilsson <> wrote:
    > somenath <> wrote:
    > > Hi All,

    >
    > > I have one question regarding return value cast of malloc.

    >
    > > I learned that we should not cast the return value of malloc
    > > because it is bug hider.
    > > But my question is as mentioned bellow .

    >
    > > Lets say I have not included stdlib.h in my program still I
    > > am using malloc so compiler will throw warring because with
    > > out prototype compiler assumes that function is declared
    > > as extern int malloc().

    >
    > If you ignore the bug, the bug remains. Even without an
    > explanation, I can't this as ever being a Good Thing (TM).
    >
    > > Suppose I ignore that warning and did not cast the return
    > > value
    > > Now during linking time my code will be linked to exact
    > > implementation of malloc which returns void * . So in this
    > > case will it be a problem?

    >
    > Yes.
    >
    > On a typical motorola 68k implementaion, the library will
    > return the pointer in A0, whereas your code will expect
    > it in D0.
    >

    Many thanks for the response. I just fell to understand this point.
    With out prototype compiler assumes that malloc returns int. But
    during linking time it will be linked to correct definition of malloc,
    which returns (void *). Then in run time it will be returning (void
    *) .Is my understanding wrong ?


    > On a stack based implementation where void * is 64 bits
    > and int is 32-bits, you may find the library function will
    > clean up too much stack.
    >


    I did not get this point either . How it is a problem ? Could you
    please illustrate this point bit more .

    > Fact is, failing to declare a prototype is seen as such
    > a weakness in the C language that many people prefer to
    > tell their compilers to make it an error to call an
    > unprototyped named function, even though it breaks the
    > conformance of the compiler. Some even go so far as use
    > C++ instead of C.


    Ok . This is the only point I understood.
    somenath, Dec 2, 2007
    #3
  4. somenath <> wrote:
    > Peter Nilsson <> wrote:
    > > somenath <> wrote:
    > > > I learned that we should not cast the return value of
    > > > malloc because it is bug hider. ...
    > > > Lets say I have not included stdlib.h in my program
    > > > still I am using malloc so compiler will throw warring
    > > > because with out prototype compiler assumes that
    > > > function is declared as extern int malloc().

    > >
    > > If you ignore the bug, the bug remains. Even without an
    > > explanation, I can't this as ever being a Good Thing (TM).
    > >
    > > > Suppose I ignore that warning and did not cast the
    > > > return value
    > > > Now during linking time my code will be linked to exact
    > > > implementation of malloc which returns void * . So in
    > > > this case will it be a problem?

    > >
    > > Yes.
    > >
    > > On a typical motorola 68k implementaion, the library will
    > > return the pointer in A0, whereas your code will expect
    > > it in D0.

    >
    > Many thanks for the response. I just fell to understand
    > this point.


    Do a google for "chinese whispers".

    C is typically implemented as a series of processes
    (roughly following the translation phases set out in
    the standard.) Each of these processes typically
    carries an element of trust.

    The compiler trusts you the programmer.
    The linker trusts the compiler.
    The host system trusts the linker.

    The weak point is at the beginning. If you lie to the
    compiler, everyone trusts each other until the program
    actually runs and problems surface.

    > With out prototype compiler assumes that malloc returns
    > int.


    Yes, and it produces some assembler that _assumes_ the
    type of value returned when it calls malloc is an int.

    On some systems, that means assuming it comes via a data
    register, rather than an address register. On other systems
    it assumes that 32 bits need to be allocated on a stack,
    instead of 64. On still other systems, it assumes it will
    arrive in the living room rather than the garage.

    Different systems have different calling conventions. Some
    systems use machine registers, some use a hardware stack,
    others have combinations of the two, and still others use
    even wierder mechanisms.

    The fundamental point though is that these calling
    conventions fall down (usually quite quickly) if the
    compiler uses the wrong one. The only clue to the
    correct one comes from you the programmer.

    > But during linking time it will be linked to correct
    > definition of malloc, which returns (void *). Then in
    > run time it will be returning (void *) .


    But _where_ this void * is returned is crucial. Since the
    compiler has been told to expect it via a completely
    different type, there is no guarantee that the assembly
    code it produces will correctly match up with how the
    function actually returns the value.

    > Is my understanding wrong ?


    You are missing the point that C is a statically
    typed language. The return type of a function is not
    determined at runtime, it is fixed at compile time. In
    this regard, C differs from many modern languages that
    prefer to figure things out as they run.

    Calling a function is like a messaging system. You
    pass arguments to the function and it returns one
    back to you (if it's a non-void function like malloc).
    How those messages are communicated are agreed to in
    advance. You stray from the agreed communication lines
    at your peril.

    Imagine you send off your courier to deliver a message
    to Malloc Pty Ltd asking for a delivery of Memory. You
    tell your assistant to pick up the returned package at
    Gate 15 of bus terminal. But Malloc Pty Ltd always
    delivers at Gate 12. So you miss the package.

    > > On a stack based implementation where void * is 64
    > > bits and int is 32-bits, you may find the library
    > > function will clean up too much stack.

    >
    > I did not get this point either. How it is a problem?
    > Could you please illustrate this point bit more .


    Suppose you send a family wagon over to Malloc Pty
    Ltd to pick up a package. They then put 2 tonnes of
    packages into the back and your tyres blow out before
    you even leave the pick up dock. Where you agreed to
    send a small utility truck, you sent a wagon, and
    now you've paid the cost.

    --
    Peter
    Peter Nilsson, Dec 2, 2007
    #4
  5. somenath <> writes:
    > On Dec 2, 10:02 am, Peter Nilsson <> wrote:
    >> somenath <> wrote:

    [...]
    >> > Suppose I ignore that warning and did not cast the return
    >> > value
    >> > Now during linking time my code will be linked to exact
    >> > implementation of malloc which returns void * . So in this
    >> > case will it be a problem?

    >>
    >> Yes.
    >>
    >> On a typical motorola 68k implementaion, the library will
    >> return the pointer in A0, whereas your code will expect
    >> it in D0.
    >>

    > Many thanks for the response. I just fell to understand this point.
    > With out prototype compiler assumes that malloc returns int. But
    > during linking time it will be linked to correct definition of malloc,
    > which returns (void *). Then in run time it will be returning (void
    > *) .Is my understanding wrong ?

    [...]

    Yes, and the inconsistency is why it's a problem.

    When the compiler sees your call to malloc, it generates code for a
    call assuming that malloc returns int. At link time, the call is
    resolved to refer to the correct malloc function, which returns void*.
    So the malloc function returns a void* result to a caller that's
    expecting an int. Hilarity ensues.

    Note that on *some* implementations, this will happen to work
    (because, say, int and void* happen to be the same size, and happen to
    be returned in the same manner). On others, Bad Things Will Happen.

    --
    Keith Thompson (The_Other_Keith) <>
    Looking for software development work in the San Diego area.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Dec 2, 2007
    #5
  6. somenath wrote:

    > Many thanks for the response. I just fell to understand this point.
    > With out prototype compiler assumes that malloc returns int. But
    > during linking time it will be linked to correct definition of malloc,
    > which returns (void *). Then in run time it will be returning (void
    > *) .Is my understanding wrong ?

    Yes.

    You're correct that it links with the right definition. However the
    compiler has told the linker that malloc returns an int.

    In a stack-based implementation, the calling function will remove an int
    from the stack (because thats what it expects). If an int is not
    identical in size to a void*, it will remove too much, or not enough,
    and corrupt memory.

    In other implementations, such as the M86K mentioned, it will try to
    read the int from entirely the wrong register, and return garbage data.

    >> On a stack based implementation where void * is 64 bits
    >> and int is 32-bits, you may find the library function will
    >> clean up too much stack.
    >>

    >
    > I did not get this point either . How it is a problem ? Could you
    > please illustrate this point bit more .


    Lets say you ask the the librarian for Knuth, and he puts two volumes on
    top of the pile on his desk. If you were expecting four volumes, then
    you will take someone else's books. When you try to use those two extra
    books you'll get in a mess. Meanwhile the guy who actually did want
    those two books will have got Advanced Calculus instead, and will be
    equally in a mess.
    Mark McIntyre, Dec 2, 2007
    #6
  7. somenath

    somenath Guest

    On Dec 2, 6:30 pm, Mark McIntyre <> wrote:
    > somenath wrote:
    > > Many thanks for the response. I just fell to understand this point.
    > > With out prototype compiler assumes that malloc returns int. But
    > > during linking time it will be linked to correct definition of malloc,
    > > which returns (void *). Then in run time it will be returning (void
    > > *) .Is my understanding wrong ?

    >
    > Yes.
    >
    > You're correct that it links with the right definition. However the
    > compiler has told the linker that malloc returns an int.
    >
    > In a stack-based implementation, the calling function will remove an int
    > from the stack (because thats what it expects). If an int is not
    > identical in size to a void*, it will remove too much, or not enough,
    > and corrupt memory.
    >


    Many thanks for the explanation. Please let me verify my understanding
    with the explanation what you have provided.

    In a stack base implementation when ever one function is called the
    arguments are pushed into the stack .Now when the called function
    returned a value it put the return value at the top of the stack .So
    the calling function can pop the value. Now as the malloc is returning
    void * but calling function is expecting int and if the size of void
    * != size of int it may pop less or more data which can cause
    problem . I would like to know if my understanding is correct?
    somenath, Dec 2, 2007
    #7
  8. somenath

    santosh Guest

    somenath wrote:

    > On Dec 2, 6:30 pm, Mark McIntyre <> wrote:
    >> somenath wrote:
    >> > Many thanks for the response. I just fell to understand this point.
    >> > With out prototype compiler assumes that malloc returns int. But
    >> > during linking time it will be linked to correct definition of
    >> > malloc, which returns (void *). Then in run time it will be
    >> > returning (void
    >> > *) .Is my understanding wrong ?

    >>
    >> Yes.
    >>
    >> You're correct that it links with the right definition. However the
    >> compiler has told the linker that malloc returns an int.
    >>
    >> In a stack-based implementation, the calling function will remove an
    >> int from the stack (because thats what it expects). If an int is not
    >> identical in size to a void*, it will remove too much, or not enough,
    >> and corrupt memory.
    >>

    > Many thanks for the explanation. Please let me verify my understanding
    > with the explanation what you have provided.
    >
    > In a stack base implementation when ever one function is called the
    > arguments are pushed into the stack .Now when the called function
    > returned a value it put the return value at the top of the stack .So
    > the calling function can pop the value. Now as the malloc is returning
    > void * but calling function is expecting int and if the size of void
    > * != size of int it may pop less or more data which can cause
    > problem . I would like to know if my understanding is correct?


    Essentially yes, but the error need not require a stack at all. Simply
    speaking if there is not prototype for malloc() in scope, the compiler
    defaults to a return type of int. Therefore it will generate calls to
    malloc() suited for an int return type. The actual implementation of
    malloc() that you link with, will of course return a void * value.

    Now there is no requirement in the Standard that void * and int have the
    same size or representation or occupy the same machine level storage
    location. For example it may so happen on an implementation that
    pointer return values are returned in register r7 while int return
    values are returned in register r0.

    Therefore when there is no prototype for malloc() and the compiler
    assumes it returns an int, it may generate something similar in terms
    of machine code for a typical call to malloc():

    C code:
    int *p = malloc(SIZE);

    Asm:
    PUSH SIZE
    CALL _malloc
    ADD 4, SP ; CLEAN UP STACK
    MOVE R0, p

    Here malloc() returned it's pointer value in register R7 (that is the
    convention for this machine), but the compiler stores the value in R0
    to the pointer object 'p' because it defaults to assuming malloc()
    returns an int, when there is no prototype for it, and in this machine
    the default location of an int return value is register R0.

    Hence some garbage value that happens to be in R0 will get stored into
    your precious pointer 'p' and the code will likely lead to a memory
    violation error when you deference the pointer, or to silent memory
    corruption.

    This example is simply an illustration of the general rule in C that
    unless the Standard says otherwise you may not assume that different
    types have any similarity with each other or are treated the same at
    the machine level.

    Overriding the type system of the language, either by an explicit cast
    or by errors like above, is dangerous, unless you know exactly what you
    are doing on a particular machine and can live with the loss of
    portability.
    santosh, Dec 2, 2007
    #8
  9. somenath wrote:
    >
    > In a stack base implementation when ever one function is called the
    > arguments are pushed into the stack .Now when the called function
    > returned a value it put the return value at the top of the stack .So
    > the calling function can pop the value. Now as the malloc is returning
    > void * but calling function is expecting int and if the size of void
    > * != size of int it may pop less or more data which can cause
    > problem . I would like to know if my understanding is correct?


    Correct.
    Mark McIntyre, Dec 2, 2007
    #9
  10. somenath

    santosh Guest

    santosh wrote:

    > somenath wrote:
    >
    >> On Dec 2, 6:30 pm, Mark McIntyre <> wrote:
    >>> somenath wrote:
    >>> > Many thanks for the response. I just fell to understand this
    >>> > point. With out prototype compiler assumes that malloc returns
    >>> > int. But during linking time it will be linked to correct
    >>> > definition of malloc, which returns (void *). Then in run time it
    >>> > will be returning (void
    >>> > *) .Is my understanding wrong ?
    >>>
    >>> Yes.
    >>>
    >>> You're correct that it links with the right definition. However the
    >>> compiler has told the linker that malloc returns an int.
    >>>
    >>> In a stack-based implementation, the calling function will remove an
    >>> int from the stack (because thats what it expects). If an int is not
    >>> identical in size to a void*, it will remove too much, or not
    >>> enough, and corrupt memory.
    >>>

    >> Many thanks for the explanation. Please let me verify my
    >> understanding with the explanation what you have provided.
    >>
    >> In a stack base implementation when ever one function is called the
    >> arguments are pushed into the stack .Now when the called function
    >> returned a value it put the return value at the top of the stack .So
    >> the calling function can pop the value. Now as the malloc is
    >> returning
    >> void * but calling function is expecting int and if the size of void
    >> * != size of int it may pop less or more data which can cause
    >> problem . I would like to know if my understanding is correct?

    >
    > Essentially yes, but the error need not require a stack at all. Simply
    > speaking if there is not prototype for malloc() in scope, the compiler
    > defaults to a return type of int. Therefore it will generate calls to
    > malloc() suited for an int return type. The actual implementation of
    > malloc() that you link with, will of course return a void * value.
    >
    > Now there is no requirement in the Standard that void * and int have
    > the same size or representation or occupy the same machine level
    > storage location. For example it may so happen on an implementation
    > that pointer return values are returned in register r7 while int
    > return values are returned in register r0.
    >
    > Therefore when there is no prototype for malloc() and the compiler
    > assumes it returns an int, it may generate something similar in terms
    > of machine code for a typical call to malloc():
    >
    > C code:
    > int *p = malloc(SIZE);


    Correction: Forgot the all important cast of malloc() return value and
    why it may lead to errors.

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

    <snip rest>
    santosh, Dec 2, 2007
    #10
  11. somenath

    Joe Wright Guest

    somenath wrote:
    > Hi All,
    >
    > I have one question regarding return value cast of malloc.
    >
    > I learned that we should not cast the return value of malloc because
    > it is bug hider.
    > But my question is as mentioned bellow .
    >
    > Lets say I have not included stdlib.h in my program still I am using
    > malloc so compiler will throw warring because with out prototype
    > compiler assumes that function is declared as extern int
    > malloc() .Suppose I ignore that warning and did not cast the return
    > value
    > Now during linking time my code will be linked to exact
    > implementation of malloc which returns void * . So in this case will
    > it be a problem?
    >
    > Regards,
    > Somenath


    Big problem. The point of prototypes is to help the compiler do the
    Right Thing. Without the prototype the compiler might do the Other
    Thing. The Linker doesn't 'fix' anything.

    In my own humble estimation, the most important and most valuable part
    of the C89 Standard was function prototypes provided in standard
    headers. Why would you use malloc() without including stdlib.h?

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
    Joe Wright, Dec 3, 2007
    #11
    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. kaeli
    Replies:
    8
    Views:
    592
    Chris Smith
    Nov 18, 2004
  2. Johannes Koch

    upper-casing parts of xpath

    Johannes Koch, Sep 17, 2004, in forum: XML
    Replies:
    3
    Views:
    601
    Kenneth Stephen
    Sep 18, 2004
  3. Darren Spruell

    urllib2 header casing discrepancy

    Darren Spruell, Feb 23, 2011, in forum: Python
    Replies:
    0
    Views:
    387
    Darren Spruell
    Feb 23, 2011
  4. Replies:
    14
    Views:
    194
  5. Replies:
    4
    Views:
    155
    RedGrittyBrick
    Jul 18, 2005
Loading...

Share This Page