Undefined behaviour question

Discussion in 'C Programming' started by Joona I Palaste, Dec 16, 2003.

  1. We all know that this:

    void *p;
    if (p=malloc(1)) {
    free(p);
    p;
    }

    causes undefined behaviour if malloc() succeeds. But what about this?

    void *p;
    if (p=malloc(1)) {
    free(p);
    &p;
    }

    I *think* this is perfectly safe and defined behaviour but as I have
    not read the standard I am not sure.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "O pointy birds, O pointy-pointy. Anoint my head, anointy-nointy."
    - Dr. Michael Hfuhruhurr
    Joona I Palaste, Dec 16, 2003
    #1
    1. Advertising

  2. Joona I Palaste wrote:

    > We all know that this:
    >
    > void *p = malloc(1);
    > if (NULL != p) {
    > free(p);
    > p;
    > }
    >
    > causes undefined behavior if malloc() succeeds. But what about this?
    >
    > void *p = malloc(1);
    > if (NULL != p) {
    > free(p);
    > &p;
    > }
    >
    > I *think* this is perfectly safe and defined behavior
    > but, as I have not read the standard, I am not sure.


    It is safe.
    Pointer p no longer points to a valid object after free(p)
    but p is still a valid pointer object
    so a pointer to p is a valid pointer object as well.
    E. Robert Tisdale, Dec 16, 2003
    #2
    1. Advertising

  3. In article <brns0u$f9v$>,
    Joona I Palaste <> wrote:

    > We all know that this:
    >
    > void *p;
    > if (p=malloc(1)) {
    > free(p);
    > p;
    > }
    >
    > causes undefined behaviour if malloc() succeeds. But what about this?
    >
    > void *p;
    > if (p=malloc(1)) {
    > free(p);
    > &p;
    > }
    >
    > I *think* this is perfectly safe and defined behaviour but as I have
    > not read the standard I am not sure.


    Of course it is perfectly safe. All you do is taking the address of an
    existing object. The fact that the object contains nonsense doesn't
    cause any problem when you take its address. You might as well ask
    whether

    void *p;
    if (p = malloc (1)) { free (p); p = NULL; }

    causes problems. After all, you are assigning NULL to a variable
    containing an undefined value.
    Christian Bau, Dec 16, 2003
    #3
  4. Joona I Palaste

    nrk Guest

    Joona I Palaste wrote:

    > We all know that this:
    >
    > void *p;
    > if (p=malloc(1)) {
    > free(p);
    > p;
    > }
    >
    > causes undefined behaviour if malloc() succeeds. But what about this?
    >
    > void *p;
    > if (p=malloc(1)) {
    > free(p);
    > &p;
    > }
    >
    > I *think* this is perfectly safe and defined behaviour but as I have
    > not read the standard I am not sure.
    >


    int i;
    int *p;

    p = &i;

    is that safe? does that answer your question? :)

    -nrk.

    --
    Remove devnull for email
    nrk, Dec 16, 2003
    #4
  5. Joona I Palaste

    Old Wolf Guest

    > We all know that this:
    >
    > void *p;
    > if (p=malloc(1)) {
    > free(p);
    > p;
    > }
    >
    > causes undefined behaviour if malloc() succeeds.


    Call me Mr. Deer-in-Headlights, but I'd always been taught that
    p;
    is a no-op.

    Furthermore, how about:

    if (p=malloc(1)) {
    int x = (int)p;
    free(p);
    x;
    }

    Casting a pointer to an int is implementation-defined (but not undefined), isn't it?

    There does not seem to be much difference between the above, and
    if (p=malloc(1)) {
    free(p);
    int x = (int)p;
    x;
    }

    My rationale: the reason it's undefined to use a pointer value (without
    dereferencing) is for systems where loading such a value to a memory
    access register causes an exception. However, if we are just converting to
    int, that register would not have to be used. Since the int cast is
    implementation-defined, the implementation could always do this
    without doing anything undefined.
    Old Wolf, Dec 17, 2003
    #5
  6. Joona I Palaste

    Ben Pfaff Guest

    (Old Wolf) writes:

    > > We all know that this:
    > >
    > > void *p;
    > > if (p=malloc(1)) {
    > > free(p);
    > > p;
    > > }
    > >
    > > causes undefined behaviour if malloc() succeeds.

    >
    > Call me Mr. Deer-in-Headlights, but I'd always been taught that
    > p;
    > is a no-op.


    It's not a no-op from the viewpoint of the standard. Rather, it
    calculates the value of variable `p'. Because the value of
    variable `p' is indeterminate (see C99 6.2.4#2) and thus may be a
    trap representation (see C99 3.17.2), that expression invokes
    undefined behavior.

    > Furthermore, how about:
    >
    > if (p=malloc(1)) {
    > int x = (int)p;
    > free(p);
    > x;
    > }


    No pointer is involved, so if the conversion `(int) p' produced
    a value that is not a trap representation, it is still not a trap
    representation after the free().

    > Casting a pointer to an int is implementation-defined (but not
    > undefined), isn't it?


    Not necessarily, see C99 6.3.2.3#6:

    If the result cannot be represented in the integer type, the
    behavior is undefined.

    > There does not seem to be much difference between the above, and
    > if (p=malloc(1)) {
    > free(p);
    > int x = (int)p;
    > x;
    > }


    That's undefined too, because the value of `p' is still being
    accessed. You could access the bytes in `p' through a character
    pointer if you like, though.

    > My rationale: the reason it's undefined to use a pointer value (without
    > dereferencing) is for systems where loading such a value to a memory
    > access register causes an exception.


    That's a reasonable reason.

    > However, if we are just converting to int, that register would
    > not have to be used.


    But it's not required not to be used. Behavior is still
    undefined.

    > Since the int cast is implementation-defined, the
    > implementation could always do this without doing anything
    > undefined.


    --
    "Welcome to the wonderful world of undefined behavior, where the demons
    are nasal and the DeathStation users are nervous." --Daniel Fox
    Ben Pfaff, Dec 17, 2003
    #6
  7. Old Wolf wrote:

    >> We all know that this:
    >>
    >> void *p;
    >> if (p=malloc(1)) {
    >> free(p);
    >> p;
    >> }
    >>
    >> causes undefined behaviour if malloc() succeeds.

    >
    > Call me Mr. Deer-in-Headlights, but I'd always been taught that
    > p;
    > is a no-op.


    In abstract terms, p is evaluated, and then that value is discarded. Whilst
    any compiler /may/ optimise it out, it isn't /required/ to. Joona is right;
    the behaviour is undefined.


    >
    > Furthermore, how about:
    >
    > if (p=malloc(1)) {
    > int x = (int)p;
    > free(p);
    > x;
    > }
    >
    > Casting a pointer to an int is implementation-defined (but not undefined),
    > isn't it?


    Yes. But in this case, all you're doing is giving x a valid (albeit
    implementation-defined) value. It /looks/ very similar to the first case,
    but in fact it isn't.

    >
    > There does not seem to be much difference between the above, and
    > if (p=malloc(1)) {
    > free(p);
    > int x = (int)p;
    > x;
    > }


    Oh, there's a world of difference. This one (quite apart from not even
    compiling on C89) exhibits undefined behaviour in line 3, because of the
    evaluation of p.

    >
    > My rationale: the reason it's undefined to use a pointer value (without
    > dereferencing) is for systems where loading such a value to a memory
    > access register causes an exception. However, if we are just converting to
    > int, that register would not have to be used.


    I can find no such guarantee in the Standard.

    > Since the int cast is
    > implementation-defined, the implementation could always do this
    > without doing anything undefined.


    A cast is a process, taking a value as input. In getting the value for input
    to the casting process, you invoke undefined behaviour, so the cast is way
    too late.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Dec 17, 2003
    #7
  8. Joona I Palaste wrote:

    > We all know that this:
    >
    > void *p;
    > if (p=malloc(1)) {
    > free(p);
    > p;
    > }
    >
    > causes undefined behaviour if malloc() succeeds.


    Correct.

    > But what about this?
    >
    > void *p;
    > if (p=malloc(1)) {
    > free(p);
    > &p;
    > }
    >
    > I *think* this is perfectly safe and defined behaviour but as I have
    > not read the standard I am not sure.


    It is. You should. If you did, then you would be.

    Probably.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Dec 17, 2003
    #8
  9. On 16 Dec 2003, Joona I Palaste wrote:

    > causes undefined behaviour if malloc() succeeds. But what about this?
    >
    > void *p;
    > if (p=malloc(1)) {
    > free(p);
    > &p;
    > }
    >
    > I *think* this is perfectly safe and defined behaviour but as I have
    > not read the standard I am not sure.


    Obviously:

    void reincarnate(void **p) { *p=malloc(1); }
    void test(void) {
    void *p;
    if (p=malloc(1)) {
    free(p);
    reincarnate(&p)
    }
    }
    Jarno A Wuolijoki, Dec 17, 2003
    #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. Dan Cernat

    undefined behaviour

    Dan Cernat, Nov 11, 2003, in forum: C++
    Replies:
    1
    Views:
    339
    Josh Sebastian
    Nov 11, 2003
  2. marbac

    Undefined behaviour

    marbac, Jul 13, 2004, in forum: C++
    Replies:
    48
    Views:
    1,330
    Default User
    Jul 20, 2004
  3. Mantorok Redgormor
    Replies:
    70
    Views:
    1,733
    Dan Pop
    Feb 17, 2004
  4. VK
    Replies:
    45
    Views:
    579
    Dr John Stockton
    Sep 12, 2006
  5. -Lost
    Replies:
    13
    Views:
    358
    Richard Cornford
    Jan 31, 2007
Loading...

Share This Page