using a freed pointer

Discussion in 'C Programming' started by Serve Laurijssen, Oct 17, 2006.

  1. Consider the following code

    char *p1 = malloc(10);
    char *p2 = malloc(10);

    if (p1 > p2)
    puts("bigger");

    free(p1);
    if (p1 > p2)
    puts("bigger");

    is this a case of UB on the second comparison? Since p1 does contain a valid
    value even though there's no valid object there anymore.
    Serve Laurijssen, Oct 17, 2006
    #1
    1. Advertising

  2. Serve Laurijssen wrote:
    > Consider the following code
    >
    > char *p1 = malloc(10);
    > char *p2 = malloc(10);
    >
    > if (p1 > p2)
    > puts("bigger");
    >
    > free(p1);
    > if (p1 > p2)
    > puts("bigger");
    >
    > is this a case of UB on the second comparison? Since p1 does contain a valid
    > value even though there's no valid object there anymore.


    Yes, it is UB. As an example:

    Consider a platform that has separate data and address registers. Also
    consider that this platform has virtual memory, and that free() unmaps
    the passed-in pointer from the address space. The mere act of loading
    the p1 pointer into a register in order to compare it to another
    platform could cause a bus error, crash the program, etc.


    --
    Clark S. Cox III
    Clark S. Cox III, Oct 17, 2006
    #2
    1. Advertising

  3. Serve Laurijssen

    Ian Malone Guest

    Clark S. Cox III wrote:
    > Serve Laurijssen wrote:
    >> Consider the following code
    >>
    >> char *p1 = malloc(10);
    >> char *p2 = malloc(10);
    >>
    >> if (p1 > p2)
    >> puts("bigger");
    >>
    >> free(p1);
    >> if (p1 > p2)
    >> puts("bigger");
    >>
    >> is this a case of UB on the second comparison? Since p1 does contain a valid
    >> value even though there's no valid object there anymore.

    >
    > Yes, it is UB. As an example:
    >
    > Consider a platform that has separate data and address registers. Also
    > consider that this platform has virtual memory, and that free() unmaps
    > the passed-in pointer from the address space. The mere act of loading
    > the p1 pointer into a register in order to compare it to another
    > platform could cause a bus error, crash the program, etc.
    >


    Strictly you can't compare pointers from different objects, I'm
    sure someone else on here will be able to say whether p1 > p2
    is implementation defined or undefined even without the free,
    but it is one of the two.

    --
    imalone
    Ian Malone, Oct 17, 2006
    #3
  4. "Clark S. Cox III" wrote:
    >
    > Serve Laurijssen wrote:
    > > Consider the following code
    > >
    > > char *p1 = malloc(10);
    > > char *p2 = malloc(10);
    > >
    > > if (p1 > p2)
    > > puts("bigger");
    > >
    > > free(p1);
    > > if (p1 > p2)
    > > puts("bigger");
    > >
    > > is this a case of UB on the second comparison? Since p1 does contain a valid
    > > value even though there's no valid object there anymore.

    >
    > Yes, it is UB. As an example:
    >
    > Consider a platform that has separate data and address registers. Also
    > consider that this platform has virtual memory, and that free() unmaps
    > the passed-in pointer from the address space. The mere act of loading
    > the p1 pointer into a register in order to compare it to another
    > platform could cause a bus error, crash the program, etc.


    Isn't it UB even if p1 isn't freed, because p1 and p2 do not point
    within the same object?

    Consider the old segmented architecture of the 8088 CPU, and assume
    that you are compiling in a mode that uses "far" pointers. If the
    mallocs happen to return:

    p1 = 0x1000:0xff00 (absolute address 0x1ff00)
    and
    p2 = 0x2000:0x0010 (absolute address 0x20010)

    The code generated by the compiler can (correctly, as far as the
    Standard is concerned) claim that "p1 > p2" is true, because the
    offset 0xff00 is greater than the offset 0x0010.

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Oct 17, 2006
    #4
  5. Serve Laurijssen

    Richard Bos Guest

    "Serve Laurijssen" <> wrote:

    > Consider the following code
    >
    > char *p1 = malloc(10);
    > char *p2 = malloc(10);
    >
    > if (p1 > p2)
    > puts("bigger");
    >
    > free(p1);
    > if (p1 > p2)
    > puts("bigger");
    >
    > is this a case of UB on the second comparison? Since p1 does contain a valid
    > value even though there's no valid object there anymore.


    It's UB both times because of comparing two pointers to different
    objects using a relational operator; it's also UB the second time for
    the reason you mention.
    I wouldn't wonder if the way some popular implementations handle this UB
    (especially the first case) is by pretending that it's legal and making
    up a reasonable-looking answer; I wouldn't wonder, either, if the next
    implementation crashed your program with a bus error or segfault.

    Richard
    Richard Bos, Oct 17, 2006
    #5
  6. Kenneth Brody wrote:
    > "Clark S. Cox III" wrote:
    >> Serve Laurijssen wrote:
    >>> Consider the following code
    >>>
    >>> char *p1 = malloc(10);
    >>> char *p2 = malloc(10);
    >>>
    >>> if (p1 > p2)
    >>> puts("bigger");
    >>>
    >>> free(p1);
    >>> if (p1 > p2)
    >>> puts("bigger");
    >>>
    >>> is this a case of UB on the second comparison? Since p1 does contain a valid
    >>> value even though there's no valid object there anymore.

    >> Yes, it is UB. As an example:
    >>
    >> Consider a platform that has separate data and address registers. Also
    >> consider that this platform has virtual memory, and that free() unmaps
    >> the passed-in pointer from the address space. The mere act of loading
    >> the p1 pointer into a register in order to compare it to another
    >> platform could cause a bus error, crash the program, etc.

    >
    > Isn't it UB even if p1 isn't freed, because p1 and p2 do not point
    > within the same object?


    Indeed, I forgot about that issue. However, to the OP: in answer to your
    question, the following is still undefined.

    char *p1 = malloc(10); //Assume that malloc succeeds
    char *p2 = p1 + 5;

    if(p1 > p2)
    puts("bigger");

    free(p1);

    /*Even attempting to compare p1 or p2 results in UB */
    if(p1 > p2)
    puts("bigger");

    --
    Clark S. Cox III
    Clark S. Cox III, Oct 17, 2006
    #6
  7. Serve Laurijssen wrote:
    > Consider the following code
    >
    > char *p1 = malloc(10);
    > char *p2 = malloc(10);
    >
    > if (p1 > p2)
    > puts("bigger");
    >
    > free(p1);
    > if (p1 > p2)
    > puts("bigger");
    >
    > is this a case of UB on the second comparison? Since p1 does contain a valid
    > value even though there's no valid object there anymore.


    Several issues:

    (1) I doubt if C assigns any meaning to pointer ordering, so why
    should you expect p1 > p2 to mean anything even if p1 and p2 are still
    allocated?

    (2) After a free(p1) I can't think of anything you can do with p1
    other than setting it to another value. Even comparing it for
    equality to another pointer sounds really iffy, and probably useless
    to boot.
    Ancient_Hacker, Oct 17, 2006
    #7
  8. "Ancient_Hacker" <> writes:
    > Serve Laurijssen wrote:
    >> Consider the following code
    >>
    >> char *p1 = malloc(10);
    >> char *p2 = malloc(10);
    >>
    >> if (p1 > p2)
    >> puts("bigger");
    >>
    >> free(p1);
    >> if (p1 > p2)
    >> puts("bigger");
    >>
    >> is this a case of UB on the second comparison? Since p1 does contain a valid
    >> value even though there's no valid object there anymore.

    >
    > Several issues:
    >
    > (1) I doubt if C assigns any meaning to pointer ordering, so why
    > should you expect p1 > p2 to mean anything even if p1 and p2 are still
    > allocated?


    Why speculate?

    C certainly does assign a meaning to pointer ordering. If it didn't,
    the ">" operator wouldn't be legal for pointer operands.

    Relational operators ("<", "<=", ">", ">=") on pointer values are
    meaningful only if both point into the same object; otherwise the
    behavior is undefined. See C99 6.5.8p5 for details; Google n1124.pdf
    for a copy of the standard (plus TC1 and TC2).

    > (2) After a free(p1) I can't think of anything you can do with p1
    > other than setting it to another value. Even comparing it for
    > equality to another pointer sounds really iffy, and probably useless
    > to boot.


    After free(p1), the value of p1 is indeterminate; referring to that
    value in any way (potentially) invokes undefined behavior. (I added
    the weasel-word "potentially" because of some subtle issues involving
    indeterminate values vs. trap representations vs. unspecified values;
    there's been a discussion recently in comp.std.c. Bottom line: Don't
    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, Oct 17, 2006
    #8
  9. Serve Laurijssen

    pete Guest

    Serve Laurijssen wrote:
    >
    > Consider the following code
    >
    > char *p1 = malloc(10);
    > char *p2 = malloc(10);
    >
    > if (p1 > p2)
    > puts("bigger");
    >
    > free(p1);
    > if (p1 > p2)
    > puts("bigger");
    >
    > is this a case of UB on the second comparison?
    > Since p1 does contain a valid
    > value even though there's no valid object there anymore.


    p1 does not contain a valid value
    because there's no valid object there anymore.

    The value of a pointer to an object type, can only be either:
    1 an adress of an object or one past
    2 a null pointer
    3 indeterminate

    --
    pete
    pete, Oct 18, 2006
    #9
    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. dg
    Replies:
    0
    Views:
    328
  2. jimjim
    Replies:
    28
    Views:
    873
    Michael Wojcik
    Apr 14, 2004
  3. David Scarlett

    Just how delicate are freed pointers?

    David Scarlett, May 16, 2004, in forum: C Programming
    Replies:
    73
    Views:
    1,288
    Dan Pop
    May 21, 2004
  4. ravi
    Replies:
    72
    Views:
    1,484
    RCollins
    Sep 14, 2004
  5. frakie

    Checking freed pointer...

    frakie, Oct 3, 2007, in forum: C Programming
    Replies:
    10
    Views:
    488
    Flash Gordon
    Oct 4, 2007
Loading...

Share This Page