How to know the memory pointed by a ptr is freed?

Discussion in 'C Programming' started by ravi, Aug 17, 2004.

  1. ravi

    ravi Guest

    I have a situation where i want to free the memory pointed by a
    pointer, only if it is not freed already. Is there a way to know
    whether the memory is freed or not?
     
    ravi, Aug 17, 2004
    #1
    1. Advertising

  2. ravi

    -berlin.de Guest

    ravi <> wrote:
    > I have a situation where i want to free the memory pointed by a
    > pointer, only if it is not freed already. Is there a way to know
    > whether the memory is freed or not?


    No. You got to store this bit of informatioon. The simplest method
    is to set all pointers that pointed to memory you free()ed to NULL.
    Than you have no chance to free() that memory region twice.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, Aug 17, 2004
    #2
    1. Advertising

  3. ravi

    Ravi Uday Guest

    "ravi" <> wrote in message
    news:cfsj55$...
    > I have a situation where i want to free the memory pointed by a
    > pointer, only if it is not freed already. Is there a way to know
    > whether the memory is freed or not?
    >


    Its generally OS/system specific.
    Generally there will be some 'poison pattern' written to the pointer if it
    has been freed.
    So the pattern might be of some clue.

    Otherwise AFAIK there are no other ways of finding out whether a pointer is
    freed apriorly..

    - Ravi
     
    Ravi Uday, Aug 17, 2004
    #3
  4. "Ravi Uday" <> writes:
    > "ravi" <> wrote in message
    > news:cfsj55$...
    > > I have a situation where i want to free the memory pointed by a
    > > pointer, only if it is not freed already. Is there a way to know
    > > whether the memory is freed or not?

    >
    > Its generally OS/system specific.
    > Generally there will be some 'poison pattern' written to the pointer if it
    > has been freed.
    > So the pattern might be of some clue.


    No, the pointer is typically left alone. The value becomes invalid,
    but the bit pattern typically (arguably always) is left unchanged.

    Given:

    char *ptr = malloc(42);
    ...
    free(ptr);

    note that ptr is passed to the free() function by value. free() has
    no access to the variable ptr, and can't modify it.

    In fact, a subsequent call to malloc() is likely to reuse the same
    address. If this happens, ptr will appear to be valid, and will
    appear to point to the newly allocated memory -- but if you then call
    free(ptr), you're going to clobber memory that was actually allocated
    for something else.

    The only way to know whether a pointer has been free()d is to keep
    track of it yourself.

    --
    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, Aug 17, 2004
    #4
  5. In article <>,
    Keith Thompson <> wrote:
    >"Ravi Uday" <> writes:
    >> "ravi" <> wrote in message
    >> news:cfsj55$...
    >> > I have a situation where i want to free the memory pointed by a
    >> > pointer, only if it is not freed already. Is there a way to know
    >> > whether the memory is freed or not?

    >>
    >> Its generally OS/system specific.
    >> Generally there will be some 'poison pattern' written to the pointer if it
    >> has been freed.
    >> So the pattern might be of some clue.

    >
    >No, the pointer is typically left alone. The value becomes invalid,
    >but the bit pattern typically (arguably always) is left unchanged.
    >
    >Given:
    >
    > char *ptr = malloc(42);
    > ...
    > free(ptr);
    >
    >note that ptr is passed to the free() function by value. free() has
    >no access to the variable ptr, and can't modify it.


    The implication was that the memory area pointed to by "ptr" would be
    scrambled in some implementation-defined way - not that ptr would itself be
    modified. The point is that if this were done, then the programmer could,
    in an implementation-specific way, tell if the memory was valid.
     
    Kenny McCormack, Aug 17, 2004
    #5
  6. ravi

    Malcolm Guest

    "Kenny McCormack" <> wrote
    [ freed pointers ]
    > The implication was that the memory area pointed to by "ptr" would be
    > scrambled in some implementation-defined way - not that ptr would itself

    be
    > modified. The point is that if this were done, then the programmer could,
    > in an implementation-specific way, tell if the memory was valid.
    >

    The implemetation is allowed to modify a pointer passed to free(). Generally
    this isn't done because it is simpler to implement free() as a normal
    function.
    Some platforms do chew garbage, but usually not in performance-critical
    mode. Anyway, this is a bad way to test a pointer. Firstly the garbage value
    might be used for real data, and secondly and more importantly,
    dereferencing a freed pointer causes undefined behaviour, so your program
    would be incorrect (even if the technique happens to work on that platform)
    ..
     
    Malcolm, Aug 17, 2004
    #6
  7. (Kenny McCormack) writes:
    > In article <>,
    > Keith Thompson <> wrote:
    > >"Ravi Uday" <> writes:
    > >> "ravi" <> wrote in message
    > >> news:cfsj55$...
    > >> > I have a situation where i want to free the memory pointed by a
    > >> > pointer, only if it is not freed already. Is there a way to know
    > >> > whether the memory is freed or not?
    > >>
    > >> Its generally OS/system specific.
    > >> Generally there will be some 'poison pattern' written to the pointer if it
    > >> has been freed.
    > >> So the pattern might be of some clue.

    > >
    > >No, the pointer is typically left alone. The value becomes invalid,
    > >but the bit pattern typically (arguably always) is left unchanged.
    > >
    > >Given:
    > >
    > > char *ptr = malloc(42);
    > > ...
    > > free(ptr);
    > >
    > >note that ptr is passed to the free() function by value. free() has
    > >no access to the variable ptr, and can't modify it.

    >
    > The implication was that the memory area pointed to by "ptr" would be
    > scrambled in some implementation-defined way - not that ptr would itself be
    > modified. The point is that if this were done, then the programmer could,
    > in an implementation-specific way, tell if the memory was valid.


    Hmm. I assumed that

    Generally there will be some 'poison pattern' written to the
    pointer if it has been freed.

    referred to writing to the pointer itself, not writing through it.

    But even if that's the case, you could still have the following:

    char *ptr;
    char *another_ptr;
    ptr = malloc(42);
    free(ptr); /* ptr is now invalid */
    another_ptr = malloc(42); /* might re-use the same memory */

    After the second malloc() call, it's likely (but by no means certain)
    that ptr will still have the same value, and that it will point to the
    chunk of memory allocated by the second call. In language terms, it's
    invalid, but there's likely to be no way to detect that.

    Bottom line: you just have to keep track of this stuff yourself.

    --
    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, Aug 17, 2004
    #7
  8. "Malcolm" <> writes:
    [...]
    > The implemetation is allowed to modify a pointer passed to
    > free(). Generally this isn't done because it is simpler to implement
    > free() as a normal function.


    This was discussed at length some time ago. I don't think there was
    any consensus that an implementation is allowed to do this. It would
    have to involve some kind of compiler "magic", since the argument to
    free() can be any pointer expression, not necessarily a reference to a
    pointer object.

    Note that if an implementation does choose to modify a pointer passed
    to free(), this could be visible to a strictly conforming program. It
    could copy a pointer object's representation to an array of unsigned
    char, call free(), copy the post-free() representation to another
    array of unsigned char, and compare the arrays. If free() is required
    to act like a function (in the sense that it can't modify its
    argument), the arrays must appear equal.

    In any case, this isn't particularly relevant for C programmers. Most
    (all?) existing implementations leave the (now invalid) value in the
    pointer object, and a program can't legitimately look at the pointer
    value after the call to free() (other than by using the unsigned char
    trick, but there's no good reason to do that).

    --
    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, Aug 17, 2004
    #8
  9. ravi

    Default User Guest

    Kenny McCormack wrote:
    >
    > In article <>,
    > Keith Thompson <> wrote:
    > >"Ravi Uday" <> writes:


    > >> Generally there will be some 'poison pattern' written to the pointer if it
    > >> has been freed.
    > >> So the pattern might be of some clue.


    > >note that ptr is passed to the free() function by value. free() has
    > >no access to the variable ptr, and can't modify it.

    >
    > The implication was that the memory area pointed to by "ptr" would be
    > scrambled in some implementation-defined way - not that ptr would itself be
    > modified. The point is that if this were done, then the programmer could,
    > in an implementation-specific way, tell if the memory was valid.


    It's still going to be Undefined Behavior to dereference that pointer.
    Not to mention that memory that has been released with a call to free()
    may well be reassigned via another call to *alloc(), so relying on some
    pattern in the memory to tell whether is valid or not is a fool's
    gambit.

    If you really are incapable of keeping track, use a memory pool manager.




    Brian Rodenborn
     
    Default User, Aug 17, 2004
    #9
  10. ravi

    CBFalconer Guest

    Malcolm wrote:
    > "Kenny McCormack" <> wrote
    >
    > [ freed pointers ]
    >> The implication was that the memory area pointed to by "ptr"
    >> would be scrambled in some implementation-defined way - not that
    >> ptr would itself be modified. The point is that if this were
    >> done, then the programmer could, in an implementation-specific
    >> way, tell if the memory was valid.

    >
    > The implemetation is allowed to modify a pointer passed to free().
    > Generally this isn't done because it is simpler to implement
    > free() as a normal function.


    No it isn't. free receives a pointer by value, and has no idea
    where the original value was stored.

    --
    "The most amazing achievement of the computer software industry
    is its continuing cancellation of the steady and staggering
    gains made by the computer hardware industry..." - Petroski
     
    CBFalconer, Aug 17, 2004
    #10
  11. ravi

    RCollins Guest

    Malcolm wrote:

    > "Kenny McCormack" <> wrote
    > [ freed pointers ]
    >
    >>The implication was that the memory area pointed to by "ptr" would be
    >>scrambled in some implementation-defined way - not that ptr would itself

    >
    > be
    >
    >>modified. The point is that if this were done, then the programmer could,
    >>in an implementation-specific way, tell if the memory was valid.
    >>

    >
    > The implemetation is allowed to modify a pointer passed to free(). Generally
    > this isn't done because it is simpler to implement free() as a normal
    > function.


    Actually, it's *required* to implement free() as a 'normal' function.
    From the C89 standard:

    <Q>
    4.10.3.2 The free function


    Synopsis

    #include <stdlib.h>
    void free(void *ptr);

    Description

    The free function causes the space pointed to by ptr to be
    deallocated, that is, made available for further allocation. If ptr
    is a null pointer, no action occurs. Otherwise, if the argument does
    not match a pointer earlier returned by the calloc , malloc , or
    realloc function, or if the space has been deallocated by a call to
    free or realloc , the behavior is undefined.
    </Q>

    The definition alone specifies (void *ptr), which is a clue that
    the value of "ptr" will not be changed.

    OTOH (to play devil's advocate here), the same document says

    <Q>
    4.10.3 Memory management functions

    The order and contiguity of storage allocated by successive calls
    to the calloc , malloc , and realloc functions is unspecified. The
    pointer returned if the allocation succeeds is suitably aligned so
    that it may be assigned to a pointer to any type of object and then
    used to access such an object in the space allocated (until the space
    is explicitly freed or reallocated). Each such allocation shall yield
    a pointer to an object disjoint from any other object. The pointer
    returned points to the start (lowest byte address) of the allocated
    space. If the space cannot be allocated, a null pointer is returned.
    If the size of the space requested is zero, the behavior is
    implementation-defined; the value returned shall be either a null
    pointer or a unique pointer. The value of a pointer that refers to
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    freed space is indeterminate.
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    </Q>

    Which would /imply/ that free() can change the value of "ptr".

    Cheers,
    Ron




    > Some platforms do chew garbage, but usually not in performance-critical
    > mode. Anyway, this is a bad way to test a pointer. Firstly the garbage value
    > might be used for real data, and secondly and more importantly,
    > dereferencing a freed pointer causes undefined behaviour, so your program
    > would be incorrect (even if the technique happens to work on that platform)
    > .
    >
    >


    --
    Ron Collins
    Air Defense/RTSC/BCS
    "I have a plan so cunning, you could put a tail on it and call it a weasel"
     
    RCollins, Aug 18, 2004
    #11
  12. ravi wrote:

    > I have a situation where I want to free the memory
    > pointed [to] by a pointer, only if it is not freed already.
    > Is there a way to know whether the memory is freed or not?


    #include <stdbool.h>
    #include <stdlib.h>

    typedef struct X {
    int pattern;
    } X;

    inline static
    X* X_new(void) {
    X* p =(X*)malloc(sizeof(X));
    p->pattern = 0X55555555;
    return p;
    }

    inline static
    bool X_valid(const X* p) {
    return p->pattern == 0X55555555;
    }

    inline static
    void X_delete(const X* p) {
    if (NULL != p)
    if (X_valid(p)) {
    ((X*)p)->pattern = 0XAAAAAAAA;
    free((void*)p);
    }
    else {
    // handle the error
    }
    }
     
    E. Robert Tisdale, Aug 18, 2004
    #12
  13. ravi

    kal Guest

    (Kenny McCormack) wrote in message news:<cftjpu$t3i$>...

    > The implication was that the memory area pointed to by "ptr" would be
    > scrambled in some implementation-defined way - not that ptr would itself be
    > modified. The point is that if this were done, then the programmer could,
    > in an implementation-specific way, tell if the memory was valid.


    Really? How amazing!

    Could someone refer me to such an implementation.
    A book/publication/webpage reference would do.
     
    kal, Aug 18, 2004
    #13
  14. ravi

    Ben Pfaff Guest

    (Kenny McCormack) writes:

    > The implication was that the memory area pointed to by "ptr" would be
    > scrambled in some implementation-defined way - not that ptr would itself be
    > modified. The point is that if this were done, then the programmer could,
    > in an implementation-specific way, tell if the memory was valid.


    Hard to believe. With "normal" hardware, there's no bit pattern
    that can be put into memory by free() that couldn't be put there
    by the previous user of the memory. Thus, you could never be
    sure that the memory was not valid for use.

    (However, such a feature might be useful for debugging
    nonetheless.)
    --
    Ben Pfaff
    email:
    web: http://benpfaff.org
     
    Ben Pfaff, Aug 18, 2004
    #14
  15. RCollins <> writes:
    > Malcolm wrote:

    [...]
    > > The implemetation is allowed to modify a pointer passed to
    > > free(). Generally this isn't done because it is simpler to
    > > implement free() as a normal function.

    >
    > Actually, it's *required* to implement free() as a 'normal' function.


    That's the point that was debated here some time ago.

    > From the C89 standard:

    [...]
    > The definition alone specifies (void *ptr), which is a clue that
    > the value of "ptr" will not be changed.


    Sure, it's a clue, but free could additionally be implemented as a
    macro:

    #define free(p) __builtin_free(p)

    which can do whatever compile-time magic is necessary to figure out
    whether the argument is an object.

    > OTOH (to play devil's advocate here), the same document says

    [...]
    > The value of a pointer that refers to
    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > freed space is indeterminate.
    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > </Q>
    >
    > Which would /imply/ that free() can change the value of "ptr".


    It's consistent with the assumption that free() cannot change the
    value of ptr. For example:

    char *p = malloc(sizeof *p);
    /*
    * Assume malloc succeeded, and the new value of p is represented
    * as 0xDEADBEEF.
    * 0xDEADBEEF is a valid address, pointing to the allocated memory.
    */
    free(p);
    /*
    * Assuming no magic, free() receives a copy of the value of p, but
    * has no way of knowing about the object p, and therefore no way
    * of modifying it. The value of p is still represented as
    * 0xDEADBEEF, but 0xDEADBEEF is now an indeterminate value.
    * The value didn't change, but it became indeterminate.
    */

    In my opinion, free(ptr) cannot legally change the value of ptr (other
    than causing it to become indeterminate), but only because a strictly
    conforming program can tell the difference if it does (by copying the
    value of ptr to an array of unsigned bytes before and after the free()
    and comparing the values). Note that directly examining the value of
    ptr itself isn't allowed after the call to free().

    --
    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, Aug 18, 2004
    #15
  16. >> char *ptr = malloc(42);
    >> ...
    >> free(ptr);
    >>
    >>note that ptr is passed to the free() function by value. free() has
    >>no access to the variable ptr, and can't modify it.

    >
    >The implication was that the memory area pointed to by "ptr" would be
    >scrambled in some implementation-defined way - not that ptr would itself be
    >modified. The point is that if this were done, then the programmer could,
    >in an implementation-specific way, tell if the memory was valid.


    How portable is this, beyond the issue of the existence of SIGSEGV
    in the first place? How likely is it the program will survive
    testing an invalid or NULL pointer (that is, the program continues
    with valid set to 0 or 1, as opposed to getting aborted with
    or without core dump).

    jmp_buf jmp;
    int handler(int sig)
    {
    longjmp(jmp, 1);
    }

    int valid;
    int *ptr;
    ... at this point ptr is set to some value that might be valid or
    might not be ...
    signal(SIGSEGV, handler);

    if (setjmp(jmp) == 0) {
    *ptr;
    /* wild guess */
    if (*ptr != 0xdeadbeef) {
    valid = 1;
    } else {
    valid = 0;
    }
    } else {
    /* here if smegfault dereferencing ptr */
    valid = 0;
    }
    ... continue here with valid set to guess about the pointer ...

    Gordon L. Burditt
     
    Gordon Burditt, Aug 18, 2004
    #16
  17. ravi

    Jack Klein Guest

    On Tue, 17 Aug 2004 16:38:17 -0700, RCollins
    <> wrote in comp.lang.c:

    >
    >
    > Malcolm wrote:
    >
    > > "Kenny McCormack" <> wrote
    > > [ freed pointers ]
    > >
    > >>The implication was that the memory area pointed to by "ptr" would be
    > >>scrambled in some implementation-defined way - not that ptr would itself

    > >
    > > be
    > >
    > >>modified. The point is that if this were done, then the programmer could,
    > >>in an implementation-specific way, tell if the memory was valid.
    > >>

    > >
    > > The implemetation is allowed to modify a pointer passed to free(). Generally
    > > this isn't done because it is simpler to implement free() as a normal
    > > function.

    >
    > Actually, it's *required* to implement free() as a 'normal' function.
    > From the C89 standard:
    >
    > <Q>
    > 4.10.3.2 The free function
    >
    >
    > Synopsis
    >
    > #include <stdlib.h>
    > void free(void *ptr);
    >
    > Description
    >
    > The free function causes the space pointed to by ptr to be
    > deallocated, that is, made available for further allocation. If ptr
    > is a null pointer, no action occurs. Otherwise, if the argument does
    > not match a pointer earlier returned by the calloc , malloc , or
    > realloc function, or if the space has been deallocated by a call to
    > free or realloc , the behavior is undefined.
    > </Q>
    >
    > The definition alone specifies (void *ptr), which is a clue that
    > the value of "ptr" will not be changed.
    >
    > OTOH (to play devil's advocate here), the same document says
    >
    > <Q>
    > 4.10.3 Memory management functions
    >
    > The order and contiguity of storage allocated by successive calls
    > to the calloc , malloc , and realloc functions is unspecified. The
    > pointer returned if the allocation succeeds is suitably aligned so
    > that it may be assigned to a pointer to any type of object and then
    > used to access such an object in the space allocated (until the space
    > is explicitly freed or reallocated). Each such allocation shall yield
    > a pointer to an object disjoint from any other object. The pointer
    > returned points to the start (lowest byte address) of the allocated
    > space. If the space cannot be allocated, a null pointer is returned.
    > If the size of the space requested is zero, the behavior is
    > implementation-defined; the value returned shall be either a null
    > pointer or a unique pointer. The value of a pointer that refers to
    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > freed space is indeterminate.
    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > </Q>
    >
    > Which would /imply/ that free() can change the value of "ptr".


    And what about the 37 copies made of that pointer after it was
    returned from malloc() and passed to free()?

    Or what about the suitably sized array of unsigned chars into which
    the bit pattern of the pointer was copied by memcpy()?

    The reason the term 'indeterminate' is used in this context is that
    the standard makes any use of an 'indeterminate' value (other than
    with an lvalue type other than unsigned char) undefined behavior.

    Consider a platform like today's common desktop, with memory
    management hardware. Freeing a pointer might cause the block of
    virtual memory that mapped to it to be removed from the program's
    address space. Attempting to dereference the pointer, or even compare
    it with NULL, could trigger an exception when it is loaded into an
    addressing register. That's a pretty good example of undefined
    behavior.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Aug 18, 2004
    #17
  18. ravi

    Jack Klein Guest

    On Tue, 17 Aug 2004 20:44:07 GMT, Default User
    <> wrote in comp.lang.c:

    > Kenny McCormack wrote:
    > >
    > > In article <>,
    > > Keith Thompson <> wrote:
    > > >"Ravi Uday" <> writes:

    >
    > > >> Generally there will be some 'poison pattern' written to the pointer if it
    > > >> has been freed.
    > > >> So the pattern might be of some clue.

    >
    > > >note that ptr is passed to the free() function by value. free() has
    > > >no access to the variable ptr, and can't modify it.

    > >
    > > The implication was that the memory area pointed to by "ptr" would be
    > > scrambled in some implementation-defined way - not that ptr would itself be
    > > modified. The point is that if this were done, then the programmer could,
    > > in an implementation-specific way, tell if the memory was valid.

    >
    > It's still going to be Undefined Behavior to dereference that pointer.
    > Not to mention that memory that has been released with a call to free()
    > may well be reassigned via another call to *alloc(), so relying on some
    > pattern in the memory to tell whether is valid or not is a fool's
    > gambit.


    It's even undefined behavior to compare the pointer to NULL, although
    I don't know of any hardware platform that would actually trap on it.
    Doesn't mean there aren't any.

    > If you really are incapable of keeping track, use a memory pool manager.


    ....or explicitly set pointers to NULL immediately after freeing, but
    that doesn't help if there might be copies around.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Aug 18, 2004
    #18
  19. ravi

    RCollins Guest

    Jack Klein wrote:

    > On Tue, 17 Aug 2004 16:38:17 -0700, RCollins
    > <> wrote in comp.lang.c:
    >


    <snip>

    >>
    >>Which would /imply/ that free() can change the value of "ptr".

    >
    >
    > And what about the 37 copies made of that pointer after it was
    > returned from malloc() and passed to free()?
    >
    > Or what about the suitably sized array of unsigned chars into which
    > the bit pattern of the pointer was copied by memcpy()?


    I don't know ... the standard doesn't mention them. All I know is that
    the prototype for free() doesn't _appear_ to allow the value of "ptr"
    to be changed. (Ignoring the possibility of behind-the-scenes
    'compiler magic'). As for those 37 copies ... I'd say it was up to
    the programmer to keep them straightened out properly.

    >
    > The reason the term 'indeterminate' is used in this context is that
    > the standard makes any use of an 'indeterminate' value (other than
    > with an lvalue type other than unsigned char) undefined behavior.


    While in a practical sense we all know what it means (or we should,
    if we're going to make a living at this stuff), in another sense it
    is somewhat ambiguous. After a call to free(), the value of "ptr"
    is indeterminate. Does that mean that there is now a random bit
    pattern stored in "ptr", or does it mean that we cannot under any
    circumstances 'view' the bit pattern stored in "ptr"?

    Of course, in the 'real world', it means neither. It simply means
    that we gave that memory back to the system and any access to it
    leads to undefined behavior.

    >
    > Consider a platform like today's common desktop, with memory
    > management hardware. Freeing a pointer might cause the block of
    > virtual memory that mapped to it to be removed from the program's
    > address space. Attempting to dereference the pointer, or even compare
    > it with NULL, could trigger an exception when it is loaded into an
    > addressing register. That's a pretty good example of undefined
    > behavior.
    >


    Does this mean I can't copy out the bit pattern and view it?
    (say, with a memcpy() into an array of unsigned chars). While
    a bit pattern representing a trap may have been copied into "ptr",
    I don't think free is _allowed_ to do that.

    Here is the question it all boils down to:

    Given that the standard specifies the prototype of free() to be
    void free(void *ptr)

    Is then free() *required* to behave that way? By the definition,
    the bit pattern of "ptr" should not change; but is 'compiler magic'
    allowed to happen here with a prototype that doesn't explicitly
    *show* the value has changed?

    Did I ask that clearly, or did I just muddle the waters?


    --
    Ron Collins
    Air Defense/RTSC/BCS
    "I have a plan so cunning, you could put a tail on it and call it a weasel"
     
    RCollins, Aug 18, 2004
    #19
  20. ravi

    RCollins Guest

    Keith Thompson wrote:

    > RCollins <> writes:
    >
    >>Malcolm wrote:

    >
    > [...]
    >
    >>>The implemetation is allowed to modify a pointer passed to
    >>>free(). Generally this isn't done because it is simpler to
    >>>implement free() as a normal function.

    >>
    >>Actually, it's *required* to implement free() as a 'normal' function.

    >
    >
    > That's the point that was debated here some time ago.


    I missed that debate; I'll try to find it on Google and
    catch up.

    >
    >
    >> From the C89 standard:

    >
    > [...]
    >
    >>The definition alone specifies (void *ptr), which is a clue that
    >>the value of "ptr" will not be changed.

    >
    >
    > Sure, it's a clue, but free could additionally be implemented as a
    > macro:
    >
    > #define free(p) __builtin_free(p)
    >
    > which can do whatever compile-time magic is necessary to figure out
    > whether the argument is an object.


    I dunno ... the standard shows the definition of free() as
    void free(void *ptr)

    If anybody looks at the standard to learn how to call free(),
    they *should* be able to count on the value (i.e. the bit pattern)
    of "ptr" not changing. (Why they would want to, I can't say).

    >
    >
    >>OTOH (to play devil's advocate here), the same document says

    >
    > [...]
    >
    >> The value of a pointer that refers to
    >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >>freed space is indeterminate.
    >>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >></Q>
    >>
    >>Which would /imply/ that free() can change the value of "ptr".

    >
    >
    > It's consistent with the assumption that free() cannot change the
    > value of ptr. For example:
    >
    > char *p = malloc(sizeof *p);
    > /*
    > * Assume malloc succeeded, and the new value of p is represented
    > * as 0xDEADBEEF.
    > * 0xDEADBEEF is a valid address, pointing to the allocated memory.
    > */
    > free(p);
    > /*
    > * Assuming no magic, free() receives a copy of the value of p, but
    > * has no way of knowing about the object p, and therefore no way
    > * of modifying it. The value of p is still represented as
    > * 0xDEADBEEF, but 0xDEADBEEF is now an indeterminate value.
    > * The value didn't change, but it became indeterminate.
    > */


    Ummm... what do you mean by "indeterminate"? I can do a memcpy()
    of the bits in "p" to an array of unsigned char, and determine
    *exactly* what the value is (or, simpler yet, since I know that
    free() did not change "p", I can simply print it out before the
    call to free() ... it will be the same after the call).

    Or do we mean that I cannot 'see' the bits in "p" at all? That sounds
    like a trap representation to me ... and traps are very deterministic
    (there's only a limited number of them).

    Or do we mean that I shouldn't be 'touching' the memory returned to
    the system by free(), because we cannot determine the state of that
    memory after the free() call?

    >
    > In my opinion, free(ptr) cannot legally change the value of ptr (other
    > than causing it to become indeterminate), but only because a strictly
    > conforming program can tell the difference if it does (by copying the
    > value of ptr to an array of unsigned bytes before and after the free()
    > and comparing the values). Note that directly examining the value of
    > ptr itself isn't allowed after the call to free().
    >


    I agree; I think the whole issue boils down to a very convoluted and
    complex warning about trying to access free()'d memory. (i.e., don't
    do it!)

    --
    Ron Collins
    Air Defense/RTSC/BCS
    "I have a plan so cunning, you could put a tail on it and call it a weasel"
     
    RCollins, Aug 18, 2004
    #20
    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. Sid
    Replies:
    5
    Views:
    1,110
  2. Heiko Vogel
    Replies:
    3
    Views:
    598
    Method Man
    Sep 14, 2004
  3. franco ziade

    const ptr to const ptr ?

    franco ziade, Feb 17, 2005, in forum: C Programming
    Replies:
    3
    Views:
    420
    franco ziade
    Feb 17, 2005
  4. G Fernandes
    Replies:
    9
    Views:
    627
    DHOLLINGSWORTH2
    Feb 27, 2005
  5. Frodo Baggins
    Replies:
    12
    Views:
    666
    dbtid
    Jan 3, 2007
Loading...

Share This Page