accessing freed memory without error

Discussion in 'C Programming' started by sachin_mzn@yahoo.com, Jan 12, 2005.

  1. Guest

    Hi,

    Why I am not getting any run time error while accessing a freed memory
    in following code. This is printing h in std output.

    #include<stdio.h>
    main()
    {
    char* buffer = (char*)malloc(6);
    strcpy(buffer,"hello");
    free(buffer);
    printf("buffer=%c\n", *buffer);
    }

    -Sachin
    , Jan 12, 2005
    #1
    1. Advertising

  2. buda Guest

    <> wrote in message
    news:...
    > Hi,
    >
    > Why I am not getting any run time error while accessing a freed memory
    > in following code. This is printing h in std output.
    >
    > #include<stdio.h>
    > main()
    > {
    > char* buffer = (char*)malloc(6);
    > strcpy(buffer,"hello");
    > free(buffer);
    > printf("buffer=%c\n", *buffer);
    > }


    You've entered the realm of undefined behaviour with the printf, and
    anything at all (including printing h on stdout) can happen. Simply don't do
    it.
    buda, Jan 12, 2005
    #2
    1. Advertising

  3. dandelion Guest

    <> wrote in message
    news:...
    > Hi,
    >
    > Why I am not getting any run time error while accessing a freed memory
    > in following code.


    C does not have any "run-time-errors". Accessing freed (i.e. non-allocated)
    memory results in undefined behavior. If pink rabbits would jump out of your
    computer, there would still be nothing wrong as far as the standard is
    concerned.

    > This is printing h in std output.
    >
    > #include<stdio.h>
    > main()
    > {
    > char* buffer = (char*)malloc(6);
    > strcpy(buffer,"hello");
    > free(buffer);


    > printf("buffer=%c\n", *buffer);


    If that would print the content of the last issue of PlayGirl, it would be
    right, too.
    > }


    Checkout the FAQ.

    http://www.eskimo.com/~scs/C-faq/q7.20.html
    dandelion, Jan 12, 2005
    #3
  4. Taran Guest

    dandelion wrote:
    > C does not have any "run-time-errors". Accessing freed (i.e.

    non-allocated)
    > memory results in undefined behavior. If pink rabbits would jump out

    of your
    > computer, there would still be nothing wrong as far as the standard

    is
    > concerned.
    > If that would print the content of the last issue of PlayGirl, it

    would be
    > right, too.
    > > }


    ROTFL. Pink Rabbits (?), PlayGirl(!) issue...
    Taran, Jan 12, 2005
    #4
  5. Mike Wahler Guest

    <> wrote in message
    news:...
    > Hi,
    >
    > Why I am not getting any run time error while accessing a freed memory
    > in following code.


    Because your program's behavior is undefined. This means
    that from the language perspective, it could do absolutely
    anything at all, from 'seems to work', to a crash, anything
    in between, or something else.

    > This is printing h in std output.


    It also might have caused the monitor to fall of the desk.
    Moral: Don't Do That.

    >
    > #include<stdio.h>


    #include <stdlib.h> /* declares 'malloc()' and 'free()' */
    #include <string.h> /* declares 'strcpy()' */

    > main()


    int main(void)

    > {
    > char* buffer = (char*)malloc(6);


    You forgot to check if 'malloc()' succeeded. If it
    failed, it returns NULL, in which case the call
    to 'strcpy()' would give undefined behavior, because
    it would try to dereference a null pointer.

    Also, your casting of 'malloc()'s return value hides a
    serious error: There's no prototype for 'malloc()' in
    scope, which will cause a C89 compiler to assume it
    returns type 'int'. So your cast tries to convert
    a pointer type to an integer type. The language
    does not define such a conversion. This conversion
    is implementation-defined, but in any case it will
    very likely corrupt the returned pointer value, in
    which case you have more undefined behavior.

    > strcpy(buffer,"hello");
    > free(buffer);
    > printf("buffer=%c\n", *buffer);


    return 0;

    > }


    It's been a while since I've seen so many errors in such
    a small piece of code. :)

    -Mike
    Mike Wahler, Jan 12, 2005
    #5
  6. wrote:
    > Hi,
    >
    > Why I am not getting any run time error while accessing a freed memory
    > in following code.


    Dumb luck. Just as using malloc() and free() without the prototypes
    found in <stdlib.h> and using strcpy without the prototype <string.h>
    gave you no error.

    > This is printing h in std output.


    Not for me. A version of your program with other errors corrected
    follows yours; note that the output is not what you claim.
    >
    > #include<stdio.h>
    > main()
    > {
    > char* buffer = (char*)malloc(6);
    > strcpy(buffer,"hello");
    > free(buffer);
    > printf("buffer=%c\n", *buffer);
    > }


    #include <stdio.h>
    #include <stdlib.h> /* note */
    #include <string.h> /* note */

    int main(void)
    {
    char *buffer = malloc(6); /* note */
    if (!buffer) {
    fprintf(stderr, "malloc failed.\n");
    exit(EXIT_FAILURE);
    }
    strcpy(buffer, "hello");
    free(buffer);
    printf("buffer=%c\n", *buffer); /* impromper use of pointer */
    return 0;
    }

    [output]
    buffer=

    BTW: please note the other threads on preserving indenting when using
    google.com. You can follow those suggestions or -- even better -- stop
    using google for posting.
    Martin Ambuhl, Jan 12, 2005
    #6
  7. dandelion Guest

    "Taran" <> wrote in message
    news:...
    >
    > dandelion wrote:
    > > C does not have any "run-time-errors". Accessing freed (i.e.

    > non-allocated)
    > > memory results in undefined behavior. If pink rabbits would jump out

    > of your
    > > computer, there would still be nothing wrong as far as the standard

    > is
    > > concerned.
    > > If that would print the content of the last issue of PlayGirl, it

    > would be
    > > right, too.
    > > > }

    >
    > ROTFL. Pink Rabbits (?), PlayGirl(!) issue...


    Hey! Can't a girl have some fun, too? ;-).
    dandelion, Jan 13, 2005
    #7
  8. On Wed, 12 Jan 2005 18:13:15 +0000, Mike Wahler wrote:

    > <> wrote in message
    > news:...


    ....

    > int main(void)
    >
    >> {
    >> char* buffer = (char*)malloc(6);

    >
    > You forgot to check if 'malloc()' succeeded. If it
    > failed, it returns NULL, in which case the call
    > to 'strcpy()' would give undefined behavior, because
    > it would try to dereference a null pointer.
    >
    > Also, your casting of 'malloc()'s return value hides a
    > serious error: There's no prototype for 'malloc()' in
    > scope, which will cause a C89 compiler to assume it
    > returns type 'int'. So your cast tries to convert
    > a pointer type to an integer type.


    Well, an int to a pointer. But that's not the problem. The code invokes
    undefined behaviour because it tries to call a function with a type that
    is not compatible with the function's definition. So the code has left the
    rails before the cast is executed.

    Lawrence
    Lawrence Kirby, Jan 13, 2005
    #8
  9. Mike Wahler Guest

    "dandelion" <> wrote in message
    news:41e6464e$0$189$4all.nl...
    >
    > "Taran" <> wrote in message
    > news:...
    > >
    > > dandelion wrote:
    > > > C does not have any "run-time-errors". Accessing freed (i.e.

    > > non-allocated)
    > > > memory results in undefined behavior. If pink rabbits would jump out

    > > of your
    > > > computer, there would still be nothing wrong as far as the standard

    > > is
    > > > concerned.
    > > > If that would print the content of the last issue of PlayGirl, it

    > > would be
    > > > right, too.
    > > > > }

    > >
    > > ROTFL. Pink Rabbits (?), PlayGirl(!) issue...

    >
    > Hey! Can't a girl have some fun, too? ;-).


    In that case, I'd think you'd want not the 'content',
    but the pictures.

    "Honey, I buy 'em for the articles, honest!"

    :)

    -Mike
    Mike Wahler, Jan 13, 2005
    #9
  10. Lawrence Kirby wrote:

    >On Wed, 12 Jan 2005 18:13:15 +0000, Mike Wahler wrote:
    >
    >
    >
    >><> wrote in message
    >>news:...
    >>
    >>

    >
    >....
    >
    >
    >
    >>int main(void)
    >>
    >>
    >>
    >>>{
    >>>char* buffer = (char*)malloc(6);
    >>>
    >>>

    >>You forgot to check if 'malloc()' succeeded. If it
    >>failed, it returns NULL, in which case the call
    >>to 'strcpy()' would give undefined behavior, because
    >>it would try to dereference a null pointer.
    >>
    >>Also, your casting of 'malloc()'s return value hides a
    >>serious error: There's no prototype for 'malloc()' in
    >>scope, which will cause a C89 compiler to assume it
    >>returns type 'int'. So your cast tries to convert
    >>a pointer type to an integer type.
    >>
    >>

    >
    >Well, an int to a pointer. But that's not the problem. The code invokes
    >

    Just wondering what will happen in a 64 bit m/c? 32 bit integer may yield a
    junk 64 bit pointer value. Because 64 bit return value of malloc has now
    truncated to 32 bit integer.

    >undefined behaviour because it tries to call a function with a type that
    >is not compatible with the function's definition. So the code has left the
    >rails before the cast is executed.
    >
    >Lawrence
    >
    >

    Krishanu
    Krishanu Debnath, Jan 13, 2005
    #10
  11. On Thu, 13 Jan 2005 21:53:36 +0530, Krishanu Debnath wrote:

    ....

    >>Well, an int to a pointer. But that's not the problem. The code invokes
    >>

    > Just wondering what will happen in a 64 bit m/c? 32 bit integer may yield a
    > junk 64 bit pointer value. Because 64 bit return value of malloc has now
    > truncated to 32 bit integer.


    It is impossible to say what will happen. There's no requrement that an
    int and a pointer return value even be returned in the same place. For
    example 68000 series processors have different data and address registers
    so an integer value might be returned in D0 and a pointer in A0. Code that
    casts from the wrong return type will likely end up looking in the wrong
    place completely for the value.

    Lawrence
    Lawrence Kirby, Jan 14, 2005
    #11
  12. On Wed, 12 Jan 2005 18:13:15 GMT, "Mike Wahler"
    <> wrote:

    > <> wrote in message
    > news:...

    <other good comments snipped>
    > > char* buffer = (char*)malloc(6);

    <snip>
    > Also, your casting of 'malloc()'s return value hides a
    > serious error: There's no prototype for 'malloc()' in
    > scope, which will cause a C89 compiler to assume it
    > returns type 'int'. So your cast tries to convert
    > a pointer type to an integer type. The language


    You mean integer to pointer.

    > does not define such a conversion. This conversion
    > is implementation-defined, but in any case it will


    Right so far.

    > very likely corrupt the returned pointer value, in
    > which case you have more undefined behavior.
    >

    Actually if probability is measured over platforms, it "very likely"
    will work "accidentally" -- on most platforms pointers are just
    addresses and addresses are really integers. But it isn't required to
    work by the standard, and you shouldn't rely on it.

    The implicit misdeclaration also provides two (more) sources of
    Undefined Behavior. malloc actually returns a pointer (void *) while
    the calling code expects it to return an int, which is then converted
    as discussed already. And its parameter is size_t, but the actual
    argument here is int, and without the prototype declaration isn't
    automatically converted. It is not required that the mechanisms for
    returning and passing different types be the same, but again, on many
    platforms they are and this "accidentally" works, although I would say
    not quite as often as the conversion. And certainly not guaranteed.

    - David.Thompson1 at worldnet.att.net
    Dave Thompson, Jan 17, 2005
    #12
  13. Flash Gordon Guest

    Mike Wahler wrote:
    > <> wrote in message
    > news:...
    >
    >>Hi,
    >>
    >>Why I am not getting any run time error while accessing a freed memory
    >>in following code.

    >
    >
    > Because your program's behavior is undefined. This means
    > that from the language perspective, it could do absolutely
    > anything at all, from 'seems to work', to a crash, anything
    > in between, or something else.
    >
    >
    >>This is printing h in std output.

    >
    >
    > It also might have caused the monitor to fall of the desk.
    > Moral: Don't Do That.
    >
    >
    >>#include<stdio.h>

    >
    >
    > #include <stdlib.h> /* declares 'malloc()' and 'free()' */
    > #include <string.h> /* declares 'strcpy()' */
    >
    >
    >>main()

    >
    >
    > int main(void)
    >
    >
    >>{
    >>char* buffer = (char*)malloc(6);

    >
    >
    > You forgot to check if 'malloc()' succeeded. If it
    > failed, it returns NULL, in which case the call
    > to 'strcpy()' would give undefined behavior, because
    > it would try to dereference a null pointer.
    >
    > Also, your casting of 'malloc()'s return value hides a
    > serious error: There's no prototype for 'malloc()' in
    > scope, which will cause a C89 compiler to assume it
    > returns type 'int'. So your cast tries to convert
    > a pointer type to an integer type. The language
    > does not define such a conversion. This conversion
    > is implementation-defined, but in any case it will
    > very likely corrupt the returned pointer value, in
    > which case you have more undefined behavior.


    It's worse than that, it is guaranteed to be undefined behaviour because
    malloc returns a void* but the OP has effectively lied to the compiler
    by making it assume an int is returned, there is no integer to pointer
    conversion invoked. It is perfectly reasonable and valid for and int to
    be returned in one register and a pointer in a different register,
    something that some implementations definitely do. So this could cause
    some random value that happens to be in a data register to be converted
    to a pointer whilst the actual return value is completely ignored.

    >>strcpy(buffer,"hello");
    >>free(buffer);
    >>printf("buffer=%c\n", *buffer);

    >
    >
    > return 0;
    >
    >
    >>}

    >
    >
    > It's been a while since I've seen so many errors in such
    > a small piece of code. :)


    Yes, it was horrendous, and very similar to lots of other such examples
    I've seen posted asking the same question.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
    Flash Gordon, Jan 17, 2005
    #13
  14. Eric Sosman Guest

    Dave Thompson wrote:
    > [concerning the use of malloc() without a declaration]
    >
    > The implicit misdeclaration also provides two (more) sources of
    > Undefined Behavior. malloc actually returns a pointer (void *) while
    > the calling code expects it to return an int, which is then converted
    > as discussed already. And its parameter is size_t, but the actual
    > argument here is int, and without the prototype declaration isn't
    > automatically converted. It is not required that the mechanisms for
    > returning and passing different types be the same, but again, on many
    > platforms they are and this "accidentally" works, although I would say
    > not quite as often as the conversion. And certainly not guaranteed.


    The not-really-`int' to pointer conversion is particularly
    likely to produce garbage on an implementation where `int' is
    narrower than `void*'. Implementations with 32-bit `int' and
    64-bit `void*' are not difficult to find.

    Similarly, the failure to convert `int' to `size_t' is
    likely to garble the argument on implementations where `size_t'
    is wider than `int', particularly if the system uses something
    like a "register pair" to hold the wider quantity. And once
    again, such systems are not hard to find: 32-bit `int' and 64-bit
    `size_t' is a fairly common combination.

    In short, I agree with Dave's "certainly not guaranteed,"
    except that I would have disouraged the practice even more
    strongly. Fortunately, C99 offers the strongest discouragement
    of all: Calling malloc() without a prior declaration is now a
    flat-out compile-time error, requiring a diagnostic.

    --
    Eric Sosman
    lid
    Eric Sosman, Jan 17, 2005
    #14
  15. bd Guest

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    wrote:

    > Hi,
    >
    > Why I am not getting any run time error while accessing a freed memory
    > in following code. This is printing h in std output.
    >
    > #include<stdio.h>
    > main()
    > {
    > char* buffer = (char*)malloc(6);
    > strcpy(buffer,"hello");
    > free(buffer);
    > printf("buffer=%c\n", *buffer);
    > }


    The effects of accessing freed memory are undefined. This means anything can
    happen, including nothing.
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.0 (GNU/Linux)

    iD8DBQFB7Bmx+hz2VlChukwRAuvUAKC0oI2YJBXOxsWO4rAzSqwer8/YtQCfVBfR
    lIVTC8MC9YidBIuG9GPcErg=
    =TQbd
    -----END PGP SIGNATURE-----
    bd, Jan 17, 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. jimjim
    Replies:
    28
    Views:
    863
    Michael Wojcik
    Apr 14, 2004
  2. ravi
    Replies:
    72
    Views:
    1,451
    RCollins
    Sep 14, 2004
  3. Rob

    Detecting freed memory

    Rob, Sep 1, 2005, in forum: C Programming
    Replies:
    6
    Views:
    353
    Keith Thompson
    Sep 1, 2005
  4. MN
    Replies:
    32
    Views:
    919
    Richard Bos
    Mar 11, 2009
  5. Replies:
    5
    Views:
    542
    James Kuyper
    May 25, 2009
Loading...

Share This Page