Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
148 views
in Technique[技术] by (71.8m points)

c++ - When I subtract memory addresses, why is the result smaller than I expected?

I have the following program:

#include <iostream>

struct X
{
    int a;
    float b;
} x[10], *p1, *p2;

int main(int argc, char *argv[])
{
    p1 = &x[1];
    p2 = &x[5];

    int i = p2 - p1;

    std::cout << i << std::endl;
}

I can visualize X's layout in memory, 10 boxes containing an int and a float, p1 will point at the beginning of the second box (x[1]) and p2 pointing at the beginning of the 6th box (x[5]):

   X   0   1  2  3  4  5  6  7  8  9
       _______________________________
    b  |__|__|__|__|__|__|__|__|__|__|
    a  |__|__|__|__|__|__|__|__|__|__|
          |           |    
          |           | 
          p1          p2

Is my drawing correct ? If so why is the result of i 4 ?
Having some difficulties understanding subtraction of two addresses ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is how pointer arithmetic works. Consider:

p1 = (x*)100;   // invalid memory address, just an example!
p2 = p1 + 1; 

At this point, p2 will not have the value 101, but rather 100 + sizeof(x) (which let's say is 8, so 108). It has been incremented not by one, but by one multiple of sizeof(x)! Conversely, subtracting an integer from a pointer actually subtracts multiples of sizeof(the pointed to type).

So now if you do int diff = p2 - p1, you would certainly expect to get 1 back, not 8! Otherwise, subtracting the number you just added would not yield the original value. Therefore, subtracting one pointer from another yields not the difference in memory addresses but the number of elements between the two pointers.

Moreover, the standard mandates that pointer subtraction is meaningless unless the two pointers point to elements in the same array (more correctly, it's undefined behavior and you are also allowed to use a pointer to "one past the last element" even if there is no such object there).

Finally, what if the compiler does not know the size of the pointed to type (i.e. the pointers are void*)? In this case, pointer arithmetic is not allowed at all. For example:

void* p = 100;
void* x = p + 1; // does not compile1

1 Some compilers may provide pointer arithmetic on void* as an extension to the language specification. In this case this statement can indeed compile and the result would depend on the specification of said extension (e.g. gcc would end up with the value 101).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...