[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 374
  • Last Modified:

pointer arithmetic.

Hi,

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

can anyone explain the output? I get 500.

Thanks.
0
mdn3din
Asked:
mdn3din
2 Solutions
 
imladrisCommented:
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
 
Kent OlsenData Warehouse Architect / DBACommented:

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
 
melodiesoflifeCommented:
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
jinijCommented:
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
 
ssnkumarCommented:
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
 
x_programmer82Commented:
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
 
mdn3dinAuthor Commented:
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
 
efnCommented:
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now