Please clear my doubt

Discussion in 'C Programming' started by Yang Lee, Nov 30, 2003.

  1. Yang Lee

    Yang Lee Guest

    Hi All,
    I have two char pointers

    char *a,*b;
    a=(char *)malloc(10);
    b=a; /*******/

    so both pointers are looking at same mamory location

    strcpy(a,"gates");
    printf("%s",b);

    Now I free pointer b;
    free(b);

    Then will pointer a be in existance or it will be also freed.
    or if I free pointer a then will b point to same location.

    Also

    a=(char *)malloc(10);
    strcpy(a,"gates");
    free(a);
    printf("%s",a); this still prints "gates " why is this happening
    even after freeing the memory? should I write
    a=NULL;

    Please help my simple querries as it will help me a lot.

    regards Lee


    --
    Posted via Mailgate.ORG Server - http://www.Mailgate.ORG
     
    Yang Lee, Nov 30, 2003
    #1
    1. Advertising

  2. "Yang Lee" <> schrieb im Newsbeitrag
    news:...
    > Hi All,
    > I have two char pointers
    >
    > char *a,*b;
    > a=(char *)malloc(10);
    > b=a; /*******/
    >
    > so both pointers are looking at same mamory location
    >
    > strcpy(a,"gates");
    > printf("%s",b);
    >
    > Now I free pointer b;
    > free(b);


    You don't free _pointer b_, you free _the memory it points_ to.
    from this moment the value in b as well as in a is no longer valid and even
    the statement

    a;
    or
    b;

    invokes undefined behavior [OT](for instance, a segment-descriptor in
    certain CPU's may no longer exist and even loading a or b into a
    CPU-register may cause a crash)[/OT]

    >
    > Then will pointer a be in existance or it will be also freed.
    > or if I free pointer a then will b point to same location.
    >
    > Also
    >
    > a=(char *)malloc(10);
    > strcpy(a,"gates");
    > free(a);
    > printf("%s",a); this still prints "gates " why is this happening
    > even after freeing the memory?


    Undefined behavior means everything can happen, your printf in your case
    just happens to work by accident, it could as well format your harddisk or
    put haircream into your toothpaste :)

    should I write
    > a=NULL;


    Good idea (IMHO)
    Dereferencing a NULL pointer is more likely to crash your application
    immidiately, telling you that somethimg is messed up.
    And by accident free()ing a NULL pointer does no harm, it's just a no-op.

    HTH
    Robert
     
    Robert Stankowic, Nov 30, 2003
    #2
    1. Advertising

  3. Yang Lee

    James Hu Guest

    On 2003-11-30, Yang Lee <> wrote:
    > char *a,*b;
    > a=(char *)malloc(10);
    > b=a; /*******/
    > strcpy(a,"gates");
    > printf("%s",b);


    Probably you should use:

    printf("%s\n", b);

    > free(b);
    >
    > Then will pointer a be in existance or it will be also freed.
    > or if I free pointer a then will b point to same location.


    Since b and a point to the same object prior to the call to free, then
    they both point to freed space after the call to free.

    > Also
    >
    > a=(char *)malloc(10);
    > strcpy(a,"gates");
    > free(a);
    > printf("%s",a);


    See the printf comment above.

    > this still prints "gates " why is this happening even after freeing
    > the memory? should I write
    >
    > a=NULL;


    You should never read from or write to an object whose lifetime has
    expired. In the case of allocated objects, their lifetime expires after
    the call to free. Compare this with automatic objects, whose lifetime
    expires when execution reaches the end of the their associated statement
    block.

    Why you see the "gates" output is not really relevant here, since you
    are invoking undefined behavior. One possible answer is that
    it is the nature of your C library implementation to not disturb the
    contents of freed memory until the memory is allocated and written to
    for a different purpose. However, it is a programming error to invoke
    undefined behavior.

    In almost all cases, a program can not reliably exploit this "do not
    disturb" behavior, even if the programmer so wishes. Considering your
    example, printf itself may allocate memory and write something for its
    own purpose there. Then your snippet above may actually cause the
    program to crash.

    -- James
     
    James Hu, Nov 30, 2003
    #3
  4. Yang Lee

    Simon Biber Guest

    "Yang Lee" <> wrote:
    > I have two char pointers
    >
    > char *a,*b;
    > a=(char *)malloc(10);
    > b=a; /*******/
    >
    > so both pointers are looking at same mamory location


    It's rude to point, especially at mammary locations. :)

    > strcpy(a,"gates");
    > printf("%s",b);
    >
    > Now I free pointer b;
    > free(b);


    All good so far. Now the value of both a and b is no longer valid.

    > Then will pointer a be in existance or it will be also freed.
    > or if I free pointer a then will b point to same location.


    Pointer a and b both store the same memory address. You have
    freed the memory at that address, so neither a nor b are now
    valid. You must not attempt to free(a) now.

    > Also
    >
    > a=(char *)malloc(10);
    > strcpy(a,"gates");
    > free(a);
    > printf("%s",a);


    Whoops -- you just used the invalid pointer value in a, so
    your program has undefined behaviour. Anything could happen.

    > this still prints "gates " why is this happening
    > even after freeing the memory?


    Anything could happen, including the possibility that the
    memory still contains what was in it before -- for now --
    but it may get reallocated or written over, some time in
    the future, so you should not rely on this behaviour.

    > should I write a=NULL;


    Only if setting it to a null pointer makes sense in your
    particular case. If you have finished with the variable
    then there is no need to change its value. If you intend
    to re-use the variable then it must be set to a valid
    pointer value at some point; if you can be sure that you
    will not attempt to read from it before that point, you
    can leave it alone until you set it to a correct value.

    --
    Simon.
     
    Simon Biber, Nov 30, 2003
    #4
  5. Yang Lee

    Dan Pop Guest

    In <> James Hu <> writes:

    >On 2003-11-30, Yang Lee <> wrote:
    >> char *a,*b;
    >> a=(char *)malloc(10);
    >> b=a; /*******/
    >> strcpy(a,"gates");
    >> printf("%s",b);

    >
    >Probably you should use:
    >
    > printf("%s\n", b);
    >
    >> free(b);
    >>
    >> Then will pointer a be in existance or it will be also freed.
    >> or if I free pointer a then will b point to same location.

    >
    >Since b and a point to the same object prior to the call to free, then
    >they both point to freed space after the call to free.


    That's hard to tell, considering that their values become indeterminate
    after the free() call. There is nothing in the standard preventing the
    implementation from turning both of them into null pointers after the
    free call, for example.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Dec 1, 2003
    #5
  6. Yang Lee

    Mac Guest

    On Sun, 30 Nov 2003 08:55:00 +0000, Yang Lee wrote:

    > Hi All,
    > I have two char pointers
    >
    > char *a,*b;
    > a=(char *)malloc(10);
    > b=a; /*******/
    >
    > so both pointers are looking at same mamory location
    >
    > strcpy(a,"gates");
    > printf("%s",b);
    >
    > Now I free pointer b;
    > free(b);
    >
    > Then will pointer a be in existance or it will be also freed.
    > or if I free pointer a then will b point to same location.
    >


    Pointer a will not be in existence, now. You MUST NOT use it. The same
    goes for pointer b. Technically, the pointers still exist, but they no
    longer point to memory you can use or inspect.

    > Also
    >
    > a=(char *)malloc(10);
    > strcpy(a,"gates");
    > free(a);
    > printf("%s",a); this still prints "gates " why is this happening
    > even after freeing the memory?


    After freeing, you are not supposed to touch or even look at the memory.
    In your case, I guess the memory was unchanged, but this is not guaranteed.

    > should I write
    > a=NULL;
    >


    I think it is a good practice to set a (and b) = NULL, after freeing. This
    gives you your best chance of detecting any accidental access. But you
    don't have to if you don't want to.

    > Please help my simple querries as it will help me a lot.
    >
    > regards Lee


    Mac
    --
     
    Mac, Dec 2, 2003
    #6
  7. Dan Pop <> spoke thus:

    > That's hard to tell, considering that their values become indeterminate
    > after the free() call. There is nothing in the standard preventing the
    > implementation from turning both of them into null pointers after the
    > free call, for example.


    Wait, what? Are you saying that

    int *a;
    a=malloc(sizeof *a); /* check against NULL omitted */
    printf( "a=%p\n", (void *)a ); /* let's say it prints 0x012345 */
    free( a );
    if( a==NULL )
    printf( "a is NULL\n" );

    that the second printf has a chance in hell of being called?
    Undoubtedly I've failed to "engage my brain," but I have no idea what
    you're talking about.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Dec 2, 2003
    #7
  8. Christopher Benson-Manica <> spoke thus:

    > free( a );
    > if( a==NULL )

    ^^^^^^^^^^^^^

    Let me guess, UB?

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Dec 2, 2003
    #8
  9. Christopher Benson-Manica <> scribbled the following:
    > Christopher Benson-Manica <> spoke thus:
    >> free( a );
    >> if( a==NULL )

    > ^^^^^^^^^^^^^


    > Let me guess, UB?


    Yes. (Or not necessarily, if a was originally NULL, in which case it
    would be a comparison NULL==NULL, which is perfectly safe.)
    But free() can't alter its argument anyway (no C function can), so the
    if statement is pointless.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "'It can be easily shown that' means 'I saw a proof of this once (which I didn't
    understand) which I can no longer remember'."
    - A maths teacher
     
    Joona I Palaste, Dec 2, 2003
    #9
  10. Yang Lee

    Simon Biber Guest

    "Christopher Benson-Manica" <> wrote:
    > > free( a );
    > > if( a==NULL )

    > ^^^^^^^^^^^^^
    >
    > Let me guess, UB?


    But you can avoid that UB:

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

    int main(void)
    {
    int *a;
    unsigned char b[sizeof a];
    a = malloc(sizeof *a);
    if(a != NULL)
    {

    /* make b hold object representation of valid pointer */
    memcpy(b, &a, sizeof a);

    /* on call to free, pointer value becomes invalid */
    free(a);

    /* but I can still compare the object representation */
    if(memcmp(&a, b, sizeof a) != 0)
    printf("the object representation of a has changed\n");
    }
    return 0;
    }

    By the function call semantics of C, I do not believe that
    the object representation of a can be changed by the
    call to free.

    --
    Simon.
     
    Simon Biber, Dec 3, 2003
    #10
  11. Yang Lee

    Dan Pop Guest

    In <3fcd5bdd$0$13498$> "Simon Biber" <> writes:

    >"Christopher Benson-Manica" <> wrote:
    >> > free( a );
    >> > if( a==NULL )

    >> ^^^^^^^^^^^^^
    >>
    >> Let me guess, UB?

    >
    >But you can avoid that UB:
    >
    >#include <stdio.h>
    >#include <stdlib.h>
    >#include <string.h>
    >
    >int main(void)
    >{
    > int *a;
    > unsigned char b[sizeof a];
    > a = malloc(sizeof *a);
    > if(a != NULL)
    > {
    >
    > /* make b hold object representation of valid pointer */
    > memcpy(b, &a, sizeof a);
    >
    > /* on call to free, pointer value becomes invalid */
    > free(a);
    >
    > /* but I can still compare the object representation */
    > if(memcmp(&a, b, sizeof a) != 0)
    > printf("the object representation of a has changed\n");
    > }
    > return 0;
    >}
    >
    >By the function call semantics of C, I do not believe that
    >the object representation of a can be changed by the
    >call to free.


    The function call semantics of C are irrelevant to the issue, because it
    need not be the function call that alters the object representation of the
    pointer. Especially considering that *all* pointers pointing to the freed
    block can suffer such an alteration.

    The value of a pointer becomes indeterminate when
    the object it points to reaches the end of its lifetime.

    Once the value has become indeterminate, you can't count on its
    representation to be the same as before. The implementation is free to do
    anything it wants with it. And you don't need a function call at all to
    achieve this:

    char *p;
    unsigned char repr[sizeof p];
    {
    char c;
    p = &c;
    memcpy(repr, &p, sizeof p);
    }
    /* the result of memcmp(&p, repr, sizeof p) can be anything now */

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Dec 3, 2003
    #11
  12. Yang Lee

    Simon Biber Guest

    "Dan Pop" <> wrote:
    [Quoting from C99 6.2.4#2]
    > The value of a pointer becomes indeterminate when
    > the object it points to reaches the end of its lifetime.


    I interpret that phrase quite differently to you. The value is
    indeterminate because it is neither a pointer to an object
    nor a null pointer. However, I do not see how the representation
    could possibly change. The standard says that the value becomes
    indeterminate; I agree with that, but I don't see how the
    representation could change.

    Here is the standard's definition of indeterminate value:
    "either an unspecified value or a trap representation"

    I fully see why the existing representation of the pointer will
    become an unspecified value, or a trap representation; I do not
    see how or why the object representation could change.

    > Once the value has become indeterminate, you can't count on its
    > representation to be the same as before. The implementation is
    > free to do anything it wants with it.


    I disagree entirely. The implementation has not taken control of
    my pointer object itself, only reclaimed the memory that it was
    pointing to. The old value of the pointer becomes indeterminate;
    either an unspecified value or a trap representation, but the
    object representation is not affected.

    --
    Simon.
     
    Simon Biber, Dec 4, 2003
    #12
  13. On Thu, 4 Dec 2003, Simon Biber wrote:
    >
    > "Dan Pop" <> wrote:
    > [Quoting from C99 6.2.4#2]
    > > The value of a pointer becomes indeterminate when
    > > the object it points to reaches the end of its lifetime.

    >
    > I interpret that phrase quite differently to you. The value is
    > indeterminate because it is neither a pointer to an object
    > nor a null pointer. However, I do not see how the representation
    > could possibly change. The standard says that the value becomes
    > indeterminate; I agree with that, but I don't see how the
    > representation could change.


    Nor do I think it can. *However*, you should remember that
    there are suddenly many fewer ways to examine that unchanged
    value without invoking UB. So, for example,

    void *a = malloc(1);
    free(a);
    assert(a == NULL);
    assert(a == &a);

    is absolutely allowed to let the first assertion succeed; or
    the second; or both at once. So the representation *can*
    change, if you do anything dumb like, say, examine the value
    of the pointer directly.

    OTOH, I think you are correct that

    void *a = malloc(1);
    unsigned char b[sizeof a];
    memcpy(b, &a, sizeof a);
    free(a);
    assert(memcmp(&a, b, sizeof a) == 0);

    is not allowed to do anything unexpected -- by which I probably
    mean that the assertion must succeed. *Unless* [lazy weasel
    words] the assertion would be allowed to fail even in the absence
    of the call to 'free' -- remembering that there can be multiple
    equal-valued representations of the same pointer, and myself
    being unclear as to whether the implementation be allowed to
    switch these representations around arbitrarily.
    E.g., could the system store a "last accessed" field inside a
    pointer value such that the field would change every time the
    pointer's value was loaded or dereferenced? That would rule out
    a lot of sneaky mem*() tricks...

    -Arthur
     
    Arthur J. O'Dwyer, Dec 4, 2003
    #13
  14. Yang Lee

    Dan Pop Guest

    In <3fcec00f$0$14031$> "Simon Biber" <> writes:

    >"Dan Pop" <> wrote:
    >[Quoting from C99 6.2.4#2]
    >> The value of a pointer becomes indeterminate when
    >> the object it points to reaches the end of its lifetime.

    >
    >I interpret that phrase quite differently to you. The value is
    >indeterminate because it is neither a pointer to an object
    >nor a null pointer. However, I do not see how the representation
    >could possibly change. The standard says that the value becomes
    >indeterminate; I agree with that, but I don't see how the
    >representation could change.


    The pointer value has changed, right? Where does the standard say that
    this change *must* preserve the representation?

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Dec 4, 2003
    #14
  15. Yang Lee

    Joe Wright Guest

    Dan Pop wrote:
    >
    > In <3fcec00f$0$14031$> "Simon Biber" <> writes:
    >
    > >"Dan Pop" <> wrote:
    > >[Quoting from C99 6.2.4#2]
    > >> The value of a pointer becomes indeterminate when
    > >> the object it points to reaches the end of its lifetime.

    > >
    > >I interpret that phrase quite differently to you. The value is
    > >indeterminate because it is neither a pointer to an object
    > >nor a null pointer. However, I do not see how the representation
    > >could possibly change. The standard says that the value becomes
    > >indeterminate; I agree with that, but I don't see how the
    > >representation could change.

    >
    > The pointer value has changed, right? Where does the standard say that
    > this change *must* preserve the representation?
    >

    I'd be interested in the Standard definition of 'indeterminate'. We
    properly pass to free() the address of an allocation made by malloc()
    for example. Neither malloc() nor free() know anything about a pointer
    object where this address might be or have been stored. free() couldn't
    change the object if it wanted to. Neither its value nor its
    representation will change. The reason it is indeterminate is that its
    value is now invalid, it doesn't point to memory we own. It joins that
    large group of 4 billion or so (32-bit) addresses whose validity cannot
    be determined.

    --
    Joe Wright http://www.jw-wright.com
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Dec 5, 2003
    #15
  16. Yang Lee

    Dan Pop Guest

    In <> Joe Wright <> writes:

    >Dan Pop wrote:
    >>
    >> In <3fcec00f$0$14031$> "Simon Biber" <> writes:
    >>
    >> >"Dan Pop" <> wrote:
    >> >[Quoting from C99 6.2.4#2]
    >> >> The value of a pointer becomes indeterminate when
    >> >> the object it points to reaches the end of its lifetime.
    >> >
    >> >I interpret that phrase quite differently to you. The value is
    >> >indeterminate because it is neither a pointer to an object
    >> >nor a null pointer. However, I do not see how the representation
    >> >could possibly change. The standard says that the value becomes
    >> >indeterminate; I agree with that, but I don't see how the
    >> >representation could change.

    >>
    >> The pointer value has changed, right? Where does the standard say that
    >> this change *must* preserve the representation?
    >>

    >I'd be interested in the Standard definition of 'indeterminate'.


    1 indeterminate value
    either an unspecified value or a trap representation

    >We
    >properly pass to free() the address of an allocation made by malloc()
    >for example.


    As I have already explained, the semantics of function calls are a
    non-issue here: you can achieve the same thing without calling any
    function at all.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Dec 5, 2003
    #16
    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. Bob Nelson

    doubt about doubt

    Bob Nelson, Jul 28, 2006, in forum: C Programming
    Replies:
    11
    Views:
    629
  2. David

    Response.Clear() doesn't clear

    David, Jan 31, 2008, in forum: ASP .Net
    Replies:
    2
    Views:
    1,038
    Mark Fitzpatrick
    Jan 31, 2008
  3. InvalidLastName

    Unrecognized element 'add' after <clear></clear>

    InvalidLastName, Feb 26, 2007, in forum: ASP .Net Web Services
    Replies:
    3
    Views:
    971
    Steven Cheng[MSFT]
    Mar 6, 2007
  4. Replies:
    0
    Views:
    566
  5. Peter Otten
    Replies:
    2
    Views:
    119
    Cousin Stanley
    Aug 10, 2013
Loading...

Share This Page