Checking pointers

Discussion in 'C Programming' started by pinkfloydhomer@gmail.com, Jul 8, 2005.

  1. Guest

    When a function is given a pointer, it is tempting to do an assert on
    the pointer to see if it is not NULL. But even if it is not NULL, it
    could still be invalid or wrong. What we really want to know is that it
    points to memory that we have access to. How about doing this:

    void f(int* p)
    {
    assert(*((char*)p) == *((char*)p);
    }

    To see if pointer points to something that I have access to?

    Is there another way of do something like this?

    /David
     
    , Jul 8, 2005
    #1
    1. Advertising

  2. Abhi Guest

    If it is invalid it will still result in exception when we do *p i.e.
    trying to access the memory...
     
    Abhi, Jul 8, 2005
    #2
    1. Advertising

  3. Flash Gordon Guest

    wrote:
    > When a function is given a pointer, it is tempting to do an assert on
    > the pointer to see if it is not NULL. But even if it is not NULL, it
    > could still be invalid or wrong. What we really want to know is that it
    > points to memory that we have access to. How about doing this:
    >
    > void f(int* p)
    > {
    > assert(*((char*)p) == *((char*)p);


    The compiler could optimise this away since it is always undefined
    behaviour (if p is not a valid pointer) or true.

    On systems where the compiler implements the test the most likely
    results with an invalid pointer are either a crash (SIGSEGV on *nix) or
    it returning true and you continuing with an invalid pointer.

    > }
    >
    > To see if pointer points to something that I have access to?
    >
    > Is there another way of do something like this?


    This has been discussed here before. There is absolutely no portable way
    to determine if a pointer is valid. If you want to know if it is
    possible on a specific implementation then ask on a group dedicated to
    that implementation.
    --
    Flash Gordon
    Living in interesting times.
    Although my email address says spam, it is real and I read it.
     
    Flash Gordon, Jul 8, 2005
    #3
  4. Guest

    wrote:
    > When a function is given a pointer, it is tempting to do an assert on
    > the pointer to see if it is not NULL. But even if it is not NULL, it
    > could still be invalid or wrong. What we really want to know is that it
    > points to memory that we have access to. How about doing this:
    >
    > void f(int* p)
    > {
    > assert(*((char*)p) == *((char*)p);
    > }
    >
    > To see if pointer points to something that I have access to?
    >
    > Is there another way of do something like this?
    >
    > /David


    If p is not a valid address, accessing it will cause exception.
    <OT>
    On a unix system, the kernel posts signal SIGSEGV to the application
    indication when it accesses any invalid address. So, first insatll
    a handler for SIGSEGV. Do a setjmp() before varifying the address
    and then do a longjump from the signal handler.
    In embedded systems, you may replace the exception handler with that
    of yours that would pass some information to the application
    whether the address was valid/invalid.
    </OT>
     
    , Jul 8, 2005
    #4
  5. Eric Sosman Guest

    wrote:
    > When a function is given a pointer, it is tempting to do an assert on
    > the pointer to see if it is not NULL. But even if it is not NULL, it
    > could still be invalid or wrong. What we really want to know is that it
    > points to memory that we have access to.


    That's not really good enough. What you really want to
    know is that the pointer points "where it ought to," which
    is much harder to characterize. Using assorted non-portable
    tricks you might be able to learn whether a pointer points to
    a valid memory location, whether it's correctly aligned for
    its type, whether the memory is readable and/or writeable,
    and maybe other things, too. If these tests fail you may
    conclude that a pointer is incorrect, but if they all pass
    you still don't know if the pointer is "right."

    > How about doing this:
    >
    > void f(int* p)
    > {
    > assert(*((char*)p) == *((char*)p);
    > }
    >
    > To see if pointer points to something that I have access to?


    If `p' doesn't have a valid pointer value, the attempt
    to use it causes undefined behavior. (Another respondent
    said "accessing it will cause exception," but he is wrong.
    "An exception" is among the things that might happen -- but
    it might not, too.) In other words, your test is reliable
    only if `p' is valid; if `p' is invalid there is no telling
    what might happen.

    > Is there another way of do something like this?


    I can think of nothing portable. And, as I've suggested
    above, I think the various non-portable tests you might be
    able to make are at best half-measures. (Confession: I have
    not personally used things like Purify or valgrind and cannot
    speak to their effectiveness -- but certainly a "spot-check"
    test unsupported by considerable additional machinery is of
    limited effectiveness.)

    C programmers find themselves doing a lot of "manual"
    memory management. This has its good side (flexibility) and
    its bad (susceptibility to error). The kind of test you
    propose can detect some kinds of errors, but my impression
    is that they are the minority: it's much more common to use
    a "stale" pointer by mistake or to make an off-by-one error
    and point to the neighbor of the intended object than it is
    to pull a completely garbage pointer right out of the blue.
    It may sound like a counsel of perfection, but I think the
    only way to survive is discipline: you need to construct little
    "mini-proofs" of correctness as you go along. It's not infallible
    (so few things are), but it seems more effective than trying
    to apply an unreliable test after the fact.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Jul 8, 2005
    #5
  6. CBFalconer Guest

    Eric Sosman wrote:
    > wrote:
    >
    >> When a function is given a pointer, it is tempting to do an
    >> assert on the pointer to see if it is not NULL. But even if it is
    >> not NULL, it could still be invalid or wrong. What we really want
    >> to know is that it points to memory that we have access to.

    >
    > That's not really good enough. What you really want to
    > know is that the pointer points "where it ought to," which
    > is much harder to characterize. Using assorted non-portable
    > tricks you might be able to learn whether a pointer points to
    > a valid memory location, whether it's correctly aligned for
    > its type, whether the memory is readable and/or writeable,
    > and maybe other things, too. If these tests fail you may
    > conclude that a pointer is incorrect, but if they all pass
    > you still don't know if the pointer is "right."


    Such tricks depend on what the pointer is supposed to point to.
    For example, in a doubly linked list, one can check that:

    (p->next>-prev == p) && (p->prev->next == p)

    (with suitable allowances for the ends of the list). My nmalloc
    mechanism for DJGPP uses this sort of thing as self protection, and
    it reduces the chance of a wild pointer destroying the entire
    malloc arena.


    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
     
    CBFalconer, Jul 8, 2005
    #6
  7. writes:
    > wrote:
    >> When a function is given a pointer, it is tempting to do an assert on
    >> the pointer to see if it is not NULL. But even if it is not NULL, it
    >> could still be invalid or wrong. What we really want to know is that it
    >> points to memory that we have access to. How about doing this:
    >>
    >> void f(int* p)
    >> {
    >> assert(*((char*)p) == *((char*)p);
    >> }
    >>
    >> To see if pointer points to something that I have access to?
    >>
    >> Is there another way of do something like this?
    >>
    >> /David

    >
    > If p is not a valid address, accessing it will cause exception.
    > <OT>
    > On a unix system, the kernel posts signal SIGSEGV to the application
    > indication when it accesses any invalid address. So, first insatll
    > a handler for SIGSEGV. Do a setjmp() before varifying the address
    > and then do a longjump from the signal handler.
    > In embedded systems, you may replace the exception handler with that
    > of yours that would pass some information to the application
    > whether the address was valid/invalid.
    > </OT>


    As others have pointed out, there is no portable way to determine
    whether a pointer is valid. There are a number of non-portable ways
    to do this check (such has catching SIGSEGV) -- but that still leaves
    the question of what to do once you've detected the error.

    An invalid pointer almost certainly indicates a bug in your program.
    Attempting to continue executing with a known bug could well cause
    more damage. Very often, the best way to handle the bug is to let the
    program die immediately, and let the operating system produce whatever
    diagnostics it can. Then fix the bug, recompile, and try again -- or
    submit a bug report and ask for your money back.

    In some cases, you might want to do some cleanup before terminating
    the program. For example, you might try to update and close any open
    files to avoid losing too much information. This can still be
    dangerous, though, if the bug can affect the cleanup code. It's often
    better to write the program so it's always in a consistent state (for
    example, any file are periodically updated); this will also handle
    things like turning off the power while the program is running.

    In some (but not all) safety-critical applications, shutting down the
    program might be the worst thing you could do. For example, you might
    have a choice between attempting to continue executing (perhaps in
    some safe mode) and letting the airplane crash. In such cases, it
    makes sense to use whatever system-specific means are available to
    detect errors -- and then kick yourself for letting such an error get
    into the production version of the program. (Many would question
    whether C is an acceptable language for such an application.)

    --
    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, Jul 8, 2005
    #7
  8. Guest

    Keith Thompson wrote:
    > writes:
    > > wrote:
    > >> When a function is given a pointer, it is tempting to do an assert on
    > >> the pointer to see if it is not NULL. But even if it is not NULL, it
    > >> could still be invalid or wrong. What we really want to know is that it
    > >> points to memory that we have access to. How about doing this:
    > >>
    > >> void f(int* p)
    > >> {
    > >> assert(*((char*)p) == *((char*)p);
    > >> }
    > >>
    > >> To see if pointer points to something that I have access to?
    > >>
    > >> Is there another way of do something like this?
    > >>
    > >> /David

    > >
    > > If p is not a valid address, accessing it will cause exception.
    > > <OT>
    > > On a unix system, the kernel posts signal SIGSEGV to the application
    > > indication when it accesses any invalid address. So, first insatll
    > > a handler for SIGSEGV. Do a setjmp() before varifying the address
    > > and then do a longjump from the signal handler.
    > > In embedded systems, you may replace the exception handler with that
    > > of yours that would pass some information to the application
    > > whether the address was valid/invalid.
    > > </OT>

    >
    > As others have pointed out, there is no portable way to determine
    > whether a pointer is valid. There are a number of non-portable ways
    > to do this check (such has catching SIGSEGV) -- but that still leaves
    > the question of what to do once you've detected the error.
    >
    > An invalid pointer almost certainly indicates a bug in your program.
    > Attempting to continue executing with a known bug could well cause
    > more damage. Very often, the best way to handle the bug is to let the
    > program die immediately, and let the operating system produce whatever
    > diagnostics it can. Then fix the bug, recompile, and try again -- or
    > submit a bug report and ask for your money back.
    >


    In embedded domain, sometimes it becomes necessary to check for the
    validity of addressses. For eg, Suppose the user wants to set a
    breakpoint at some address (the address being entered as an input by
    the user) then it is necessary to validate that address because it
    may be possible that user has given some invalid address.
    Similarly, while taking memory dumps, the user address must be
    validated.
    But all this is platform specific.
     
    , Jul 9, 2005
    #8
    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. Phil
    Replies:
    1
    Views:
    650
    llewelly
    Sep 16, 2003
  2. muser
    Replies:
    3
    Views:
    766
    Ron Natalie
    Sep 18, 2003
  3. A
    Replies:
    3
    Views:
    459
    Alan Kelon
    Oct 29, 2003
  4. copx
    Replies:
    7
    Views:
    377
    Mark McIntyre
    Mar 24, 2006
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    682
Loading...

Share This Page