• C

pointer arithmetic.


main( )
         int *p,*q;

can anyone explain the output? I get 500.

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

When you increment a pointer by "1", it is supposed to point to the next element. So, assuming the pointer is pointing to an array of characters, adding 1 will add 1 to the address so that it points to the next character in the array.
However, if it is pointing to an array of integers, and if integers are 4 bytes on your machine, then adding 1 will add *4* to the address, so that it will now point to the next integer.

Pointer subtraction is similar. I would assume that you in fact have a compiler/system in which integers are 2 bytes. Thus the number of integers between 1000 and 2000 would be 500.
Kent OlsenDBACommented:

Hi mdn3din,

The anomaly that you're seeing has to do with how addresses are kept on Intel chips.  In the (very) old days, 16-bit processors kept the address as SEGMENT:OFFSET.  16 bits were used for both the segment and the offset, which suggests that you could have 2**32 addressable locations, but it didn't work that way.  In fact, memories were limited to 640K and the SEGMENT:OFFSET method actually meant that there were many combinations that pointed to the same address.  For example, 0002:0001 points to segment 2, offset 1.  0001:0009 points to segment 1, offset 9.  But they BOTH map to byte 17 (Segment * 8 + offset).  So when you try to perform the pointer math that you have in your example, the result is going to be based on the SEGMENT:OFFSET value in the pointer.  An integer value of 1000 is NOT the same as address value of 1000.

As a test, try the following:

main ()
  int i, *p, *q;

  p = 1000;
  q = 2000;

  for (i = 1; i < 4; i++)
    printf (" %5d %5d\n", i, q-i);
  printf (" %5d\n", q-1000);

What you'll see is something like this:

      1  1996
      2  1992
      3  1988

Now try changing the print statement in your program to be:

printf ("%d", q-(int)p);

You should get the same answer as the last line above:


This is because you're now subtracting 1000 as a value instead of as an address.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
I don't think your program can run because you set a pointer (p, q) equal to a number. In fact, compiler will understand that the number (1000, 2000 ...) is an address in memory so the pointer p, q will point to an address in memory. Usually, this address is protected by OS, so compiler will generate error:
"Memory access violation"
The Firewall Audit Checklist

Preparing for a firewall audit today is almost impossible.
AlgoSec, together with some of the largest global organizations and auditors, has created a checklist to follow when preparing for your firewall audit. Simplify risk mitigation while staying compliant all of the time!

integer defenition  2 bytes      |     4 bytes
Location of P           1000         |         1000
Location of P+1         1002         |         1004

Location of Q=P+500   2000        |Q=P+250  2000

You will get 2 different answers depending on integer defenition
There is no compiler error like "Memory access violation"! Compiler never checks if an address is a valid one or not. Only during execution, this can be checked.
Even during execution, just by assigning an invalid address, you will not get any error or CRASH! You can always allocate to address 0 (which is invalid).......and any other invalid address....!
But, problem arises, when you try to dereference this pointer pointing to this invalid address......and your program will crash ("Segmentation fault, core dumped" or "Bus error" will be the error message) and a core containing the image of the process when the crash happened (using which you can get a stack trace and try to debug and see why it crashed....!) will get created....

....Hope I have made the point clear...!?
1000 . . . . . . . . . . .2000
^                          ^
|                           |
p                           q

in your compilerinteger size is 2

in normal arithmetic you should get 1000.(suppose int p=1000,q=2000).

But in pointer arithmetic you will get answer depending on what it points(here it points int).p-q means that how many integers cud be stored between p and q.Ofviously if int size 2 then you can store 500 integers
if int size 4 u cud store 250 integers.

mdn3dinAuthor Commented:

Tried this,

void main(void)
      int i,*q;

I get 1-1998 2-1996 ... 1000-0.So my integers are two bytes.

When I change 'int i' to 'int *i' I get, 1-999 3-998 5-997 ... 999-500.
When I change 'q-i' to 'q-(int)i' I get, 1-1998 3-1994 ... 999-2.

(pointer +/- pointer) : Normal arithmetic on pointers.
(pointer +/- integer) : Pointer arithmetic on pointers.

It's not quite as general as you showed.  The possibilities are:

integer + integer = integer
integer - integer = integer

Of course.

integer + pointer = pointer
pointer + integer = pointer

The integer denotes a number of objects of the type the pointer addresses.  The result pointer is the operand pointer plus the size of that many objects.

pointer + pointer

This is not allowed.

integer - pointer

This is not allowed either.

pointer - integer = pointer

The pointer is decreased by the size of the number of objects specified by the integer.

pointer - pointer = integer

The integer is the number of objects that fit between the two pointers.

It may be helpful to think of the pointers as absolute and the integers as relative.  For example, you could think of a pointer as an absolute time and an integer as a time interval.  So the rules above would be like this:

Wednesday + 2 = Friday
2 + Wednesday = Friday

Tuesday + Thursday is not allowed
2 - Friday is not allowed

Friday - 2 = Wednesday
Friday - Wednesday = 2

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.