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

From: Keith Thompson (kst-u_at_mib.org)
Date: 08/19/04


Date: Thu, 19 Aug 2004 19:48:14 GMT

RCollins <rcoll@nospam.theriver.com> writes:
[...]
> No, this is too deep. Given the standard's definition of free(),
> then I should be able to do this:
>
> #include <stdio.h>
>
> int mail(void) {
> unsigned long before, after;
> int *ptr;
>
> ptr = malloc(100); /* ignore possible errors for now */
> before = (unsigned long) ptr;
> free(ptr);
> after = (unsigned long) ptr;
>
> if (before == after) printf("bits in ptr have not changed\n")
> else printf("bits in ptr HAVE changed\n");
>
> return 0;
> }

ITYM "main", not "mail" (though of course a function called "mail" is
perfectly valid). And you're probably assuming that an int* will fit
into an unsigned long, which isn't guaranteed.

After the call to free(), the value if ptr is indeterminate. Any
reference to that value, even to convert it to unsigned long, causes
undefined behavior. On most or all real-world systems, the converson
just copies the bits, but it could, for example, load the pointer
value into an address register and trap if the pointer value is
invalid.

Here's my version of your program. Since refers to the representation
of ptr, not to its value as a pointer, it doesn't invoke undefined
behavior.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
    int *ptr;
    unsigned char *before;
    unsigned char *after;

    /*
     * We assume for now that all malloc() calls are successful.
     */
    ptr = malloc(sizeof *ptr);
    before = malloc(sizeof ptr);
    memcpy(before, &ptr, sizeof ptr);
    free(ptr);
    after = malloc(sizeof ptr);
    memcpy(after, &ptr, sizeof ptr);

    if (memcmp(before, after, sizeof ptr) == 0) {
        printf("bits in ptr have not changed\n");
    }
    else {
        printf("bits in ptr have changed\n");
    }
    free(before);
    free(after);

    return 0;
}

This program (assuming all the malloc()s succeed) can print "bits in
ptr have changed" only if there's some compiler magic asociated with
the free() call that fiddles with ptr, even though the free() function
has no way within the language to know where ptr is, or even that the
argument was an object reference.

In my opinion, a conforming compiler cannot perform such magic. It's
not covered by the "as-if" rule because a program can detect it. A
*reasonable* program cannot detect it, and I wouldn't complain if the
standard were amended to allow this particular magic, but I don't
think that's going to happen.

> Keep in mind the OP's original question: is there any way to know
> if the bit representation in "ptr" is a valid memory location?

And the answer is: no, there's no portable way to do that. There may
be non-portable ways to do it, but only by depending on detailed
knowledge of the implementation (which could easily change with the
next release of the system).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <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.


Relevant Pages

  • Re: About C++ memory management
    ... int * ptr = new int; ... delete ptr; ... But if I copy this pointer like below should I also delete copied ... Foo ...
    (microsoft.public.vc.language)
  • Re: How to know the memory pointed by a ptr is freed?
    ... > perfectly valid). ... And you're probably assuming that an int* will fit ... > After the call to free, the value if ptr is indeterminate. ... > just copies the bits, but it could, for example, load the pointer ...
    (comp.lang.c)
  • Re: About C++ memory management
    ... int * ptr = new int; ... delete ptr; ... But if I copy this pointer like below should I also delete copied pointer? ... Foo ...
    (microsoft.public.vc.language)
  • Re: About C++ memory management
    ... I know that every pointer allocated by using new operator should be ... int * ptr = new int; ... delete ptr; ... Foo ...
    (microsoft.public.vc.language)
  • Re: Memory Structure Pointer Problems
    ... typedef struct sta { ... char* name; ... int num_cmpnds; ... A pointer to a struct cmp is almost ...
    (comp.lang.c)