Subtracting Addresses

I am trying to wrap my head around the way in which variables are stored in memory, so i wrote a small program using an array of pointers to subtract two addresses to calculate the difference. When using pointer or array notation, incrementing the pointer will cause it to point to the next element. This would lead one to conclude the difference between two memory addresses is always 1. On the other hand, variables require a certain amount of space to be stored. So an int, for example, would require at least 4 nibbles or 16-bits leading one to conclude that the difference between two addresses in memory is 4 in hex. Clearly i am convoluting matters somehow, but the program i wrote produces output open to both interpretations:


0018FD24 - 0018FD20 = 1
Type is:int

0018FD10 - 0018FD08 = 1
Type is:int


I shall also include the source code for the program i wrote:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 #include <iostream>
#include <typeinfo>
#include <iomanip>

using std::cout;
using std::hex;

int main(void)
{
	int numArray[] = {0, 0};
	double douArray[] = {0.0, 0.0};
	
	int* pArray [] = {&numArray[0], &numArray[1]};
	// We declare and initialize an array of pointers of type int* to the first and second element, we are only interested in the addresses

	double* pdArray [] = {&douArray[0], &douArray[1]};

	cout << hex << pArray[1] << " - " << pArray[0] << " = " << pArray[1] - pArray[0]  << "\n";
	// An int is 2 bytes, so the difference between the two addresses should be 4 nibbles, 2 bytes or 1 word. The difference in hex should be 4 for
	// 2 bytes (= 4 nibbles). The result 1 refers to 1 word for 1 int?
	cout << "Type is:" << typeid(pArray[1] - pArray[0]).name() << "\n\n";

	cout << hex << pdArray[1] << " - " << pdArray[0] << " = " << pdArray[1] - pdArray[0]  << "\n";
	cout << "Type is:" << typeid(pdArray[1] - pdArray[0]).name() << "\n\n";

	return 0;
}


Can someone tell me where my reasoning errs?
I think that the best I can say is to cite the C++ Standard ( I bolded some text by myself)

5.7 Additive operators
6 When two pointers to elements of the same array object are subtracted, the result is the difference of the subscripts of the two array elements. The type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as std::ptrdiff_t in the <cstddef> header (18.2). As with any other arithmetic overflow, if the result does not fit in the space provided, the behavior is undefined. In other words, if the expressions P and Q point to, respectively, the i-th and j-th elements of an array object, the expression (P)-(Q) has the value i − j provided the value fits in an object of type std::ptrdiff_t. Moreover, if the expression P points either to an element of an array object or one past the last element of an array object, and the expression Q points to the last element of the same array object, the expression ((Q)+1)-(P) has the same value as ((Q)-(P))+1 and as -((P)-((Q) 1)), and has the value zero if the expression P points one past the last element of the array object, even though the expression (Q)+1 does not point to an element of the array object. Unless both pointers point to elements of the same array object, or one past the last element of the array object, the behavior is undefined.82


Last edited on
Thank you for the quick reply. So i guess the outcome of this subtraction will always be the number of elements seperating the two addresses in memory. So one can't use 'address arithmetic' to infer the type of the array? Even though i can see how far the addresses are apart in memory myself, i can't get it as output in the console screen?
A am sorry but I have not understood what you are speaking about.
You can output any address in the console. What is the problem?
No, sorry, i should have explained myself more clearly. I wanted to calculate the size of a single element of an array through subtracting their addresses, though thanks to your answer i now understand that i cannot go about it that way since the value returned will always be a signed int. I'll mark the topic as solved. Thanks again.
If you have a pointer to type T that is T * you can get the size in bytes of an object of type T,For example

T *p;

std::cout << sizeof( *p ) << std:;endl;



Yes, that was also my solution. I added the following lines of code to get the size of a single element:

1
2
	cout << sizeof *pArray[0] << "\n";
	cout << sizeof *pdArray[0] << "\n\n";


Thanks again for helping me out though, it is good to know why my program produces the results it does.
Topic archived. No new replies allowed.