Solved

pointer arithmetic.

Posted on 2003-11-17
10
365 Views
Last Modified: 2010-04-15
Hi,

main( )
{
         int *p,*q;
         p=1000;
         q=2000;
         printf("%d",q-p);
}

can anyone explain the output? I get 500.

Thanks.
0
Comment
Question by:mdn3din
10 Comments
 
LVL 16

Expert Comment

by:imladris
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.
0
 
LVL 45

Accepted Solution

by:
Kdo earned 25 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
 -2000

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:

 -2000

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

0
 
LVL 6

Expert Comment

by:melodiesoflife
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"
0
 

Expert Comment

by:jinij
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
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 8

Expert Comment

by:ssnkumar
ID: 9786039
melodiesoflife,
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...!?
0
 

Expert Comment

by:x_programmer82
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.

0
 

Author Comment

by:mdn3din
ID: 9805574
Hi,

Tried this,

void main(void)
{
      int i,*q;
      q=2000;
      for(i=1;i<=1000;i++)
            printf("%d-%d\t",i,q-i);
}

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.


???
0
 
LVL 15

Assisted Solution

by:efn
efn earned 25 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

--efn
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

747 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now