Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer arithmetics with two different buffers

Consider the following code:

int* p1 = new int[100];
int* p2 = new int[100];
const ptrdiff_t ptrDiff = p1 - p2;

int* p1_42 = &(p1[42]);
int* p2_42 = p1_42 + ptrDiff;

Now, does the Standard guarantee that p2_42 points to p2[42]? If not, is it always true on Windows, Linux or webassembly heap?

like image 628
Sergey Avatar asked Jan 28 '19 11:01

Sergey


People also ask

Why arithmetic operators are not used with pointers?

We can perform arithmetic operations on the pointers like addition, subtraction, etc. However, as we know that pointer contains the address, the result of an arithmetic operation performed on the pointer will also be a pointer if the other operand is of type integer.

Which arithmetic operations are not allowed on pointers?

Pointer multiplication, division, and addition are not permitted because they do not make sense in pointer arithmetic. In Python, there are seven arithmetic operators: addition, subtraction, multiplication, division, and modulus, Exponentiation.

What are the rules for pointer arithmetic?

When a pointer is incremented, it actually increments by the number equal to the size of the data type for which it is a pointer. For Example: If an integer pointer that stores address 1000 is incremented, then it will increment by 2(size of an int) and the new address it will points to 1002.

Can we subtract two pointers in C?

Two pointers can also be subtracted from each other if the following conditions are satisfied: Both pointers will point to elements of same array; or one past the last element of same array. The result of the subtraction must be representable in ptrdiff_t data type, which is defined in stddef.

How to do pointer arithmetic between two pointers of the same type?

If we have two pointers p1 and p2 of base type pointer to int with addresses 1000 and 1016 respectively, then p2 - p1 will give 4, since the size of int type is 4 bytes. If you subtract p2 from p1 i.e p1 - p2 then the answer will be negative i.e -4. The following program demonstrates pointer arithmetic between two pointers of the same type.

How does the two-pointer technique work in C++?

Now let’s see how the two-pointer technique works. We take two pointers, one representing the first element and other representing the last element of the array, and then we add the values kept at both the pointers.

What is pointer arithmetic?

Pointer arithmetic is slightly different from arithmetic we normally use in our daily life. The only valid arithmetic operations applicable on pointers are: The pointer arithmetic is performed relative to the base type of the pointer.

Can we perform every type of arithmetic operations with pointers?

We can't perform every type of arithmetic operations with pointers. Pointer arithmetic is slightly different from arithmetic we normally use in our daily life. The only valid arithmetic operations applicable on pointers are:


Video Answer


2 Answers

To add the standard quote:

expr.add#5

When two pointer expressions P and Q are subtracted, 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 ([support.types]).

  • (5.1) If P and Q both evaluate to null pointer values, the result is 0.

  • (5.2) Otherwise, if P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i−j.

  • (5.3) Otherwise, the behavior is undefined. [ Note: If the value i−j is not in the range of representable values of type std::ptrdiff_­t, the behavior is undefined. — end note  ]

(5.1) does not apply as the pointers are not nullptrs. (5.2) does not apply because the pointers are not into the same array. So, we are left with (5.3) - UB.

like image 127
Max Langhof Avatar answered Oct 16 '22 13:10

Max Langhof


const ptrdiff_t ptrDiff = p1 - p2;

This is undefined behavior. Subtraction between two pointers is well defined only if they point to elements in the same array. ([expr.add] ¶5.3).

When two pointer expressions P and Q are subtracted, 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 ([support.types]).

  • If P and Q both evaluate to null pointer values, the result is 0.
  • Otherwise, if P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i−j.
  • Otherwise, the behavior is undefined

And even if there was some hypothetical way to obtain this value in a legal way, even that summation is illegal, as even a pointer+integer summation is restricted to stay inside the boundaries of the array ([expr.add] ¶4.2)

When an expression J that has integral type is added to or subtracted from an expression P of pointer type, the result has the type of P.

  • If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value.
  • Otherwise, if P points to element x[i] of an array object x with n elements,81 the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n and the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n.
  • Otherwise, the behavior is undefined.
like image 29
Matteo Italia Avatar answered Oct 16 '22 14:10

Matteo Italia