malloced union member

Discussion in 'C Programming' started by rohit, May 19, 2004.

  1. rohit

    rohit Guest

    Hi,

    Iam confused as to when is the memory freed in this program.

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    union test{
    char *i;
    char *ch;
    };

    int main()
    {
    union test test;
    test.ch = malloc(6);
    strcpy(test.ch,"hello");
    printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    [%p]\n",test.i,test.ch,test.i,test.ch);
    free(test.i);
    printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    [%p]\n",test.i,test.ch,test.i,test.ch);
    free(test.ch);
    printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    [%p]\n",test.i,test.ch,test.i,test.ch);

    return 0;
    }

    And the output I get from my solaris box is :
    test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]

    regards
    rohitash
    rohit, May 19, 2004
    #1
    1. Advertising

  2. rohit

    Richard Bos Guest

    (rohit) wrote:

    > Iam confused as to when is the memory freed in this program.
    >
    > union test{
    > char *i;
    > char *ch;
    > };
    >
    > int main()
    > {
    > union test test;
    > test.ch = malloc(6);
    > strcpy(test.ch,"hello");
    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > [%p]\n",test.i,test.ch,test.i,test.ch);
    > free(test.i);


    It is free()d here...

    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > [%p]\n",test.i,test.ch,test.i,test.ch);


    ....so this statement invokes undefined behaviour.

    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]


    Yes, appearing to work as "normal" is one of the legal results of
    undefined behaviour. Should you now be tempted to abuse this feature,
    beware! Appearing to work as normal on your testing machines but
    crashing spectacularly on your customer's network is _also_ a legal
    result of UB...

    Richard
    Richard Bos, May 19, 2004
    #2
    1. Advertising

  3. rohit

    Stephen L. Guest

    rohit wrote:
    >
    > Hi,
    >
    > Iam confused as to when is the memory freed in this program.
    >
    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <string.h>
    >
    > union test{
    > char *i;
    > char *ch;
    > };
    >
    > int main()
    > {
    > union test test;
    > test.ch = malloc(6);
    > strcpy(test.ch,"hello");
    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > [%p]\n",test.i,test.ch,test.i,test.ch);
    > free(test.i);


    Why are you `free()'ing "test.i" here?
    You allocated the memory to "test.ch"
    (even though both elements of the union
    happen to contain the same pointer value,
    that's a very bad practice).

    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > [%p]\n",test.i,test.ch,test.i,test.ch);
    > free(test.ch);


    You got lucky here. You've `free()'d the same
    pointer value _twice_. You've corrupted your heap.

    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > [%p]\n",test.i,test.ch,test.i,test.ch);
    >
    > return 0;
    > }
    >
    > And the output I get from my solaris box is :
    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    >
    > regards
    > rohitash


    It looks like you're expecting the call to `free()'
    to somehow change the contents of the object the
    pointer was pointing to, or even the pointer itself.
    The value of a pointer after a call to `free()'
    is indeterminate.

    In this particular case, you were able to dereference
    the pointer and it still contained your original
    value. This is dumb luck.

    To answer your question, the memory obtained by
    a call to `malloc()' is "free" at the point of entry
    into the call to `free()'. "free" is a non-specific
    term, however, and should be taken to mean that it
    is not "free" for your program to access any longer.
    Some architectues may generate an error accessing
    the memory through that pointer, some may do nothing,
    and some may give the _appearence_ that the memory
    is still valid and contains valid data (as on your
    Solaris box).


    HTH,

    Stephen
    Stephen L., May 19, 2004
    #3
  4. rohit

    Richard Bos Guest

    "Stephen L." <> wrote:

    > rohit wrote:
    > > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > > [%p]\n",test.i,test.ch,test.i,test.ch);
    > > free(test.ch);

    >
    > You got lucky here. You've `free()'d the same
    > pointer value _twice_. You've corrupted your heap.


    You don't know this. It invokes undefined behaviour; this _may_ mean
    corrupting his heap, but it may also mean ignoring the statement,
    crashing with a segmentation fault, or mailing his resume to
    .

    Richard
    Richard Bos, May 19, 2004
    #4
  5. rohit

    Stephen L. Guest

    Richard Bos wrote:
    >
    > "Stephen L." <> wrote:
    >
    > > rohit wrote:
    > > > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > > > [%p]\n",test.i,test.ch,test.i,test.ch);
    > > > free(test.ch);

    > >
    > > You got lucky here. You've `free()'d the same
    > > pointer value _twice_. You've corrupted your heap.

    >
    > You don't know this. It invokes undefined behaviour; this _may_ mean
    > corrupting his heap, but it may also mean ignoring the statement,
    > crashing with a segmentation fault, or mailing his resume to ...
    >
    > Richard


    man malloc(3c) for details.

    Posters who have identified this behavioral
    aspect of `free()' have usually noted it by stating
    that their (next) `malloc()'/`free()' core dumps.

    The second call to `free()' with the same pointer
    value as before qualifies as a "random" value.

    "Undefined results will occur if the space assigned by
    malloc() is overrun or if some random number is
    passed to free()."

    -Solaris 8 man page

    It _doesn't_ say, "and BTW, the heap is fine."
    A reasonable and valid conclusion based on the facts
    as presented in the man page (along with other sources)
    is that the heap, after a `free()'ing the same
    pointer twice, is not usable, even if `free()'
    seemed to return okay. I see nothing in the man
    page(s) which would bring me to any of the
    conclusions you've arrived at - why are posters
    trying to DEFINE undefined behavior?

    I think it's important to try to answer the OP's
    question at the level (not in a condescending manner)
    that it is asked. The OP didn't say he was using
    any special implementation of `malloc()' (there
    are versions out there that perform allocation
    using much more sophisticated rules and memory models),
    so it was reasonable to assume he was using the
    "standard malloc-from-the-heap implementation".
    If I was wrong, I'd expect the OP to repost
    with a clarification - that's how the dialog
    should continue.

    But providing garbage answers like "mailing his
    resume to ..." really hurt the credibility of
    the group as a whole, IMHO.


    Stephen
    Stephen L., May 19, 2004
    #5
  6. rohit

    Dan Pop Guest

    In <> (Richard Bos) writes:

    > (rohit) wrote:
    >
    >> Iam confused as to when is the memory freed in this program.
    >>
    >> union test{
    >> char *i;
    >> char *ch;
    >> };
    >>
    >> int main()
    >> {
    >> union test test;
    >> test.ch = malloc(6);
    >> strcpy(test.ch,"hello");
    >> printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    >> [%p]\n",test.i,test.ch,test.i,test.ch);
    >> free(test.i);

    >
    >It is free()d here...


    Nope, this call merely invokes undefined behaviour.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, May 19, 2004
    #6
  7. rohit

    Dan Pop Guest

    In <> (rohit) writes:

    >Iam confused as to when is the memory freed in this program.


    What else could you expect from a bogus program?

    >#include <stdlib.h>
    >#include <stdio.h>
    >#include <string.h>
    >
    >union test{
    > char *i;
    > char *ch;
    >};


    What is the point of this union?

    >int main()
    >{
    > union test test;
    > test.ch = malloc(6);
    > strcpy(test.ch,"hello");
    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    >[%p]\n",test.i,test.ch,test.i,test.ch);


    Undefined behaviour: you can't evaluate test.i after initialising test.ch
    as they have incompatible types that can't be aliased.

    > free(test.i);


    Undefined behaviour, for the same reason as above.

    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    >[%p]\n",test.i,test.ch,test.i,test.ch);


    Undefined behaviour.

    > free(test.ch);


    Undefined behaviour. This call would have been correct as the *first*
    free call. Now, it is too late...

    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    >[%p]\n",test.i,test.ch,test.i,test.ch);


    Undefined behaviour.

    > return 0;
    >}
    >
    >And the output I get from my solaris box is :
    >test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    >test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    >test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]


    There is no way to get any enlightment from the output of a meaningless
    program. Instead of wasting your time writing and executing junk code,
    read the FAQ!

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, May 19, 2004
    #7
  8. rohit

    Lew Pitcher Guest

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

    Dan Pop wrote:
    | In <>
    (rohit) writes:
    |
    |
    |>Iam confused as to when is the memory freed in this program.
    |
    |
    | What else could you expect from a bogus program?
    |
    |
    |>#include <stdlib.h>
    |>#include <stdio.h>
    |>#include <string.h>
    |>
    |>union test{
    |> char *i;
    |> char *ch;
    |>};
    |
    |
    | What is the point of this union?
    |
    |
    |>int main()
    |>{
    |> union test test;
    |> test.ch = malloc(6);
    |> strcpy(test.ch,"hello");
    |> printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    |>[%p]\n",test.i,test.ch,test.i,test.ch);
    |
    |
    | Undefined behaviour: you can't evaluate test.i after initialising test.ch
    | as they have incompatible types that can't be aliased.

    Dan, I'm confused.

    Given the OP's union, I don't understand how test.i and test.ch can have
    "incompatable types that can't be aliased".

    AFAICT, test.i is a pointer to char, and test.ch is a pointer to char. To me,
    those don't look like "incompatable types".

    Did I read something wrong? Could you clear up my misunderstanding?



    [snip]

    - --
    Lew Pitcher

    Master Codewright & JOAT-in-training | GPG public key available on request
    Registered Linux User #112576 (http://counter.li.org/)
    Slackware - Because I know what I'm doing.
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (GNU/Linux)
    Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

    iD8DBQFArBfkagVFX4UWr64RAsM8AJ4gHH989fW30y+lOcUSGEJEULytjgCeNOQ8
    8O8w2bmyTSUPcpD6qVJYaAk=
    =u+rD
    -----END PGP SIGNATURE-----
    Lew Pitcher, May 20, 2004
    #8
  9. rohit

    Neil Kurzman Guest

    rohit wrote:

    > Hi,
    >
    > Iam confused as to when is the memory freed in this program.
    >
    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <string.h>
    >
    > union test{
    > char *i;
    > char *ch;
    > };
    >
    > int main()
    > {
    > union test test;
    > test.ch = malloc(6);
    > strcpy(test.ch,"hello");
    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > [%p]\n",test.i,test.ch,test.i,test.ch);
    > free(test.i);
    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > [%p]\n",test.i,test.ch,test.i,test.ch);
    > free(test.ch);
    > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > [%p]\n",test.i,test.ch,test.i,test.ch);
    >
    > return 0;
    > }
    >
    > And the output I get from my solaris box is :
    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    > test.i == hello test.ch == hello test.i == [209b8] test.ch == [209b8]
    >
    > regards
    > rohitash


    The memory is "freed" when you call free(). free() lets the system know
    that the memory is not used. It does not have to erase it. So you can
    still look at it (on you system). But other systems may not let you look
    at memory you do not own. freeing memory you do not own is never good.
    it is a good idea to set you pointers to NULL after free() you can then
    check them for NULL to insure you do not use pointers that no loner
    pointing to memory you own.
    Neil Kurzman, May 20, 2004
    #9
  10. rohit

    Dan Pop Guest

    In <lJUqc.30066$> Lew Pitcher <> writes:

    >-----BEGIN PGP SIGNED MESSAGE-----
    >Hash: SHA1
    >
    >Dan Pop wrote:
    >| In <>
    >(rohit) writes:
    >|
    >|
    >|>Iam confused as to when is the memory freed in this program.
    >|
    >|
    >| What else could you expect from a bogus program?
    >|
    >|
    >|>#include <stdlib.h>
    >|>#include <stdio.h>
    >|>#include <string.h>
    >|>
    >|>union test{
    >|> char *i;
    >|> char *ch;
    >|>};
    >|
    >|
    >| What is the point of this union?
    >|
    >|
    >|>int main()
    >|>{
    >|> union test test;
    >|> test.ch = malloc(6);
    >|> strcpy(test.ch,"hello");
    >|> printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    >|>[%p]\n",test.i,test.ch,test.i,test.ch);
    >|
    >|
    >| Undefined behaviour: you can't evaluate test.i after initialising test.ch
    >| as they have incompatible types that can't be aliased.
    >
    >Dan, I'm confused.
    >
    >Given the OP's union, I don't understand how test.i and test.ch can have
    >"incompatable types that can't be aliased".
    >
    >AFAICT, test.i is a pointer to char, and test.ch is a pointer to char. To me,
    >those don't look like "incompatable types".
    >
    >Did I read something wrong? Could you clear up my misunderstanding?


    My mistake, I interpreted test.ch as having the type pointer to char and
    test.i pointer to int, despite the fact that I have actually looked at the
    union definition....

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, May 21, 2004
    #10
  11. rohit

    Richard Bos Guest

    "Stephen L." <> wrote:

    > Richard Bos wrote:
    > >
    > > "Stephen L." <> wrote:
    > >
    > > > rohit wrote:
    > > > > printf("test.i == %s test.ch == %s test.i == [%p] test.ch ==
    > > > > [%p]\n",test.i,test.ch,test.i,test.ch);
    > > > > free(test.ch);
    > > >
    > > > You got lucky here. You've `free()'d the same
    > > > pointer value _twice_. You've corrupted your heap.

    > >
    > > You don't know this. It invokes undefined behaviour; this _may_ mean
    > > corrupting his heap, but it may also mean ignoring the statement,
    > > crashing with a segmentation fault, or mailing his resume to ...

    >
    > man malloc(3c) for details.


    Your particular system's manual pages are immaterial. This is
    comp.lang.c, not comp.lang.stephen-l-s-system.manpage.c. Just because
    _your_ system defines that using free() on an already free()d pointer
    corrupts "your heap", that doesn't mean you can assume all systems do.

    > Posters who have identified this behavioral
    > aspect of `free()' have usually noted it by stating
    > that their (next) `malloc()'/`free()' core dumps.


    Note: _usually_.

    > "Undefined results will occur if the space assigned by
    > malloc() is overrun or if some random number is
    > passed to free()."


    _Exactly_. _Undefined_ results. _Not_ "the heap will be corrupted".

    > It _doesn't_ say, "and BTW, the heap is fine."


    Neither does it say "and the heap will be corrupted", but that is what
    you claimed would happen. It _may_ happen. It _may_ also mail a love
    letter to your supervisor.

    > page(s) which would bring me to any of the
    > conclusions you've arrived at - why are posters
    > trying to DEFINE undefined behavior?


    I don't know. _You_ are the one trying to do so, by claiming that it
    _will_ corrupt the heap. I merely pointed out that undefined behaviour
    means that you don't even know that this is true.

    > But providing garbage answers like "mailing his
    > resume to ..." really hurt the credibility of
    > the group as a whole, IMHO.


    I'm so sorry. Could you please provide a quote from the Standard (note:
    _not_ your system-specific man pages) which shows me the error of my
    ways, by stating that undefined behaviour may _not_ result in a resume
    being mailed?

    Richard
    Richard Bos, May 24, 2004
    #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. Matt Garman
    Replies:
    1
    Views:
    667
    Matt Garman
    Apr 25, 2004
  2. Replies:
    21
    Views:
    748
    Michael Wojcik
    Sep 29, 2005
  3. Kumar McMillan
    Replies:
    0
    Views:
    417
    Kumar McMillan
    Apr 19, 2007
  4. Replies:
    18
    Views:
    745
  5. Noob
    Replies:
    18
    Views:
    361
    Tim Rentsch
    Jun 12, 2013
Loading...

Share This Page