pointer arithmetic.

Posted on 2003-11-17
Medium Priority
Last Modified: 2010-04-15

main( )
         int *p,*q;

can anyone explain the output? I get 500.

Question by:mdn3din
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 16

Expert Comment

ID: 9765912
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.
LVL 46

Accepted Solution

Kent Olsen earned 100 total points
ID: 9766204

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.


Expert Comment

ID: 9769348
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"
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.


Expert Comment

ID: 9778274
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

Expert Comment

ID: 9786039
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...!?

Expert Comment

ID: 9804834
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.


Author Comment

ID: 9805574

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.

LVL 15

Assisted Solution

efn earned 100 total points
ID: 9806252
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


Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question