beginner's question on pointer arithmetic

Discussion in 'C Programming' started by subramanian100in@yahoo.com, India, Mar 12, 2007.

  1. , India

    , India Guest

    Supoose we have,

    int x;

    int *p = &x;

    int *q;

    q = p + 1;

    Is calculating p+1 correct ? My uderstanding is that, only for arrays,
    we can take the address of one element past the end of array. In this
    case, p + 1 should invoke undefined bahaviour even if it produces
    sizeof(int) bytes beyond the location of x.

    Am I wrong ?
     
    , India, Mar 12, 2007
    #1
    1. Advertising

  2. , India said:

    > Supoose we have,
    >
    > int x;
    >
    > int *p = &x;
    >
    > int *q;
    >
    > q = p + 1;
    >
    > Is calculating p+1 correct ?


    You can calculate it, but that's all. You can't deref it.

    > My uderstanding is that, only for arrays,
    > we can take the address of one element past the end of array.


    For this purpose, an object can be considered equivalent to an array of
    one object.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Mar 12, 2007
    #2
    1. Advertising

  3. , India

    bluejack Guest

    On Mar 11, 8:43 pm, ", India"
    <> wrote:
    > Supoose we have,
    >
    > int x;
    > int *p = &x;
    > int *q;
    > q = p + 1;
    >
    > Is calculating p+1 correct ? My uderstanding is that, only for arrays,
    > we can take the address of one element past the end of array. In this
    > case, p + 1 should invoke undefined bahaviour even if it produces
    > sizeof(int) bytes beyond the location of x.


    In practical terms, q is now pointing to memory one int* beyond p; the
    contents of that memory are entirely unknown to you, and attempting to
    do anything with that memory is where you'll run into trouble.

    (Since you never assigned anything to x or to *p, attempting to do
    access the contents of x, *p, or *q are also going to run into
    trouble.)

    I'm not a standards guru, so I can't tell you whether this trouble is
    "undefined behavior" or not, but *writing* to memory that has never
    been allocated (also called "smashing memory") is the source of the
    nastiest bugs to track down, and probably the number one reason for
    avoiding pointer arithmetic. (Imagine the memory address you have now
    pointed q at is the start of a string that is used somewhere else in
    the code entirely; setting that to '0' terminates the string; while
    you're trying to figure out why that string disappears, you might
    never think to look in *this* block of code. Nasty stuff.)

    Reading from uninitialized memory can also be confusing, as *most* of
    the time, that uninitialized value might be 0, like you expect, but
    then occasionally it's not, which also makes for some headaches. Bugs
    that can't reliably be reproduced are never fun. <OT> Also, some
    compilers will 0 out uninitialized automatic variables on low levels
    of optimization, but not on higher levels; so if you compile in a
    debug mode during development, and then add optimization when you're
    ready to release your product: voila, bugs you've never seen before.
    Again, not fun.</OT>
     
    bluejack, Mar 12, 2007
    #3
  4. , India

    santosh Guest

    , India wrote:
    > Supoose we have,
    >
    > int x;
    > int *p = &x;
    > int *q;
    > q = p + 1;
    >
    > Is calculating p+1 correct ?


    Yes.

    > My uderstanding is that, only for arrays,
    > we can take the address of one element past the end of array.


    An object can be considered as an array of one element.

    > In this
    > case, p + 1 should invoke undefined bahaviour even if it produces
    > sizeof(int) bytes beyond the location of x.


    No. Pointing to one past the object is okay, but deferencing it will
    invoke undefined behaviour.
     
    santosh, Mar 12, 2007
    #4
  5. , India

    Guest

    "In practical terms, q is now pointing to memory one int* beyond p;"

    In fact, q is now pointing to memory one int (not int *)beyond p.



    On 3ÔÂ12ÈÕ, ÏÂÎç12ʱ16·Ö, "bluejack" <> wrote:
    > On Mar 11, 8:43 pm, ", India"
    >
    > <> wrote:
    > > Supoose we have,

    >
    > > int x;
    > > int *p = &x;
    > > int *q;
    > > q = p + 1;

    >
    > > Is calculating p+1 correct ? My uderstanding is that, only for arrays,
    > > we can take the address of one element past the end of array. In this
    > > case, p + 1 should invoke undefined bahaviour even if it produces
    > > sizeof(int) bytes beyond the location of x.

    >
    > In practical terms, q is now pointing to memory one int* beyond p; the
    > contents of that memory are entirely unknown to you, and attempting to
    > do anything with that memory is where you'll run into trouble.
    >
    > (Since you never assigned anything to x or to *p, attempting to do
    > access the contents of x, *p, or *q are also going to run into
    > trouble.)
    >
    > I'm not a standards guru, so I can't tell you whether this trouble is
    > "undefined behavior" or not, but *writing* to memory that has never
    > been allocated (also called "smashing memory") is the source of the
    > nastiest bugs to track down, and probably the number one reason for
    > avoiding pointer arithmetic. (Imagine the memory address you have now
    > pointed q at is the start of a string that is used somewhere else in
    > the code entirely; setting that to '0' terminates the string; while
    > you're trying to figure out why that string disappears, you might
    > never think to look in *this* block of code. Nasty stuff.)
    >
    > Reading from uninitialized memory can also be confusing, as *most* of
    > the time, that uninitialized value might be 0, like you expect, but
    > then occasionally it's not, which also makes for some headaches. Bugs
    > that can't reliably be reproduced are never fun. <OT> Also, some
    > compilers will 0 out uninitialized automatic variables on low levels
    > of optimization, but not on higher levels; so if you compile in a
    > debug mode during development, and then add optimization when you're
    > ready to release your product: voila, bugs you've never seen before.
    > Again, not fun.</OT>
     
    , Mar 12, 2007
    #5
  6. , India

    bluejack Guest

    On Mar 11, 9:47 pm, wrote:
    > "In practical terms, q is now pointing to memory one int* beyond p;"
    >
    > In fact, q is now pointing to memory one int (not int *)beyond p.


    Ooops. Exactly so. Tx!
     
    bluejack, Mar 12, 2007
    #6
  7. bluejack wrote:
    > On Mar 11, 8:43 pm, ", India"
    > <> wrote:


    > > Supoose we have,
    > >
    > > int x;
    > > int *p = &x;
    > > int *q;
    > > q = p + 1;
    > >
    > > Is calculating p+1 correct ? My uderstanding is that, only for arrays,
    > > we can take the address of one element past the end of array. In this
    > > case, p + 1 should invoke undefined bahaviour even if it produces
    > > sizeof(int) bytes beyond the location of x.

    >
    > In practical terms, q is now pointing to memory one int* beyond p; the
    > contents of that memory are entirely unknown to you, and attempting to
    > do anything with that memory is where you'll run into trouble.
    >
    > (Since you never assigned anything to x or to *p, attempting to do
    > access the contents of x, *p, or *q are also going to run into
    > trouble.)
    >
    > I'm not a standards guru, so I can't tell you whether this trouble is
    > "undefined behavior" or not,


    it is


    > but *writing* to memory that has never
    > been allocated (also called "smashing memory") is the source of the
    > nastiest bugs to track down, and probably the number one reason for
    > avoiding pointer arithmetic.


    you could just try doing the pointer arithmetic correctly.


    > (Imagine the memory address you have now
    > pointed q at is the start of a string that is used somewhere else in
    > the code entirely; setting that to '0' terminates the string; while
    > you're trying to figure out why that string disappears, you might
    > never think to look in *this* block of code. Nasty stuff.)
    >
    > Reading from uninitialized memory can also be confusing, as *most* of
    > the time, that uninitialized value might be 0, like you expect,


    well I wouldn't. What implementation zeros newly allocated (whatever
    *that* means) memory?


    > but
    > then occasionally it's not, which also makes for some headaches. Bugs
    > that can't reliably be reproduced are never fun. <OT> Also, some
    > compilers will 0 out uninitialized automatic variables on low levels
    > of optimization, but not on higher levels; so if you compile in a
    > debug mode during development, and then add optimization when you're
    > ready to release your product: voila, bugs you've never seen before.
    > Again, not fun.</OT>



    --
    Nick Keighley
     
    Nick Keighley, Mar 12, 2007
    #7
  8. , India

    bluejack Guest

    On Mar 12, 2:21 am, "Nick Keighley" <>
    wrote:

    > bluejack wrote:
    > > but *writing* to memory that has never
    > > been allocated (also called "smashing memory") is the source of the
    > > nastiest bugs to track down, and probably the number one reason for
    > > avoiding pointer arithmetic.

    >
    > you could just try doing the pointer arithmetic correctly.


    Of course; but to someone who is apparently new at this, I thought I
    would explain some of the hazards. No need to be snide.

    > > Reading from uninitialized memory can also be confusing, as *most* of
    > > the time, that uninitialized value might be 0, like you expect,

    >
    > well I wouldn't. What implementation zeros newly allocated (whatever
    > *that* means) memory?


    Of course you wouldn't. Again, I'm pointing out the hazards to someone
    who hasn't been caught in them yet. I find as more students graduate
    having been trained on java they actually do have these kinds of
    expectations, or perhaps *intuitions* of how things work by default.

    GCC zeros stack allocated variables at -O0, but not at higher levels
    of optimization. Or at least it used to; this isn't something I test
    regularly.

    -b
     
    bluejack, Mar 12, 2007
    #8
  9. , India

    santosh Guest

    bluejack wrote:
    > "Nick Keighley" <> wrote:
    > > bluejack wrote:

    [ ... ]

    > > > Reading from uninitialized memory can also be confusing, as *most* of
    > > > the time, that uninitialized value might be 0, like you expect,

    > >
    > > well I wouldn't. What implementation zeros newly allocated (whatever
    > > *that* means) memory?

    [ ... ]

    > GCC zeros stack allocated variables at -O0, but not at higher levels
    > of optimization. Or at least it used to; this isn't something I test
    > regularly.


    Apparently not anymore, or at least, not my installation, (gcc 4.0.3
    i686.)
     
    santosh, Mar 12, 2007
    #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. Shawn
    Replies:
    11
    Views:
    570
    Gregory Pietsch
    Jul 21, 2004
  2. joshc
    Replies:
    5
    Views:
    588
    Keith Thompson
    Mar 31, 2005
  3. Kenneth Brody

    Pointer arithmetic question

    Kenneth Brody, Jan 20, 2006, in forum: C Programming
    Replies:
    23
    Views:
    1,590
    Keith Thompson
    Jan 23, 2006
  4. somenath
    Replies:
    1
    Views:
    308
    Kalle Olavi Niemitalo
    Dec 23, 2007
  5. somenath

    pointer arithmetic question.

    somenath, May 6, 2012, in forum: C Programming
    Replies:
    10
    Views:
    629
    Tim Rentsch
    May 12, 2012
Loading...

Share This Page