Hamza Kyamanywa
Hamza Kyamanywa

Reputation: 588

Adding integer to null pointer address is returning unexpected result

#include <stdio.h>

int main() {
  int *numPtrA = NULL;         // pointer to an integer pointer to null.. ascii value of zero
 
  printf("%p\n", numPtrA + 2); // prints 0x8 which i expect
  printf("%p\n", numPtrA + 5); // prints 0x14 and i dont know why
}

I am trying to print the address 0x14 by adding something to the ASCII code of the null pointer which I believe is the 0 address. However, when I add 5 to NULL and I don't understand why I get 0x14 instead of 0x20. I thought since ptrNumA is a pointer to an integer it should add about 5 blocks of integers (4 bytes each) and the new address should be 0x20

I appreciate any help. Thank you so much.

Upvotes: -3

Views: 779

Answers (3)

eerorika
eerorika

Reputation: 238461

Technically, numPtrA doesn't point to an array nor even a singular object, and therefore adding anything other than 0 to it results in undefined behaviour in C++ because pointer arithmetic is only defined for pointers within bounds of arrays and objects.

Here is the quote from latest C++ standard draft:

[expr.add]

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. [does not apply]
  • Otherwise, if P points to an array element i of an array object x with n elements ... [does not apply] (note: pointers to objects can be considered as arrays of 1 element for purposes of this rule)
  • Otherwise, the behavior is undefined.

Besides that technicality, 0x prefix denotes hexadecimal base. 5 * 4 = 20 = 0x14 and 0x20 = 32 != 20.

That said, the value of null pointer is not necessarily 0 (even though the literal 0 is always a null pointer literal), so the expectation is not portable to some systems where that isn't the case. This is typical on embedded systems where address 0 is wanted for actual storage.

Furthermore, printf specifier %p requires the argument to be of type void* while you pass an int* as argument. As a result of violating this constraint, the behaviour of the program is undefined.

Upvotes: 2

Lundin
Lundin

Reputation: 215255

You aren't allowed to do pointer arithmetic on pointers that don't point to valid objects - it's undefined behavior (as per 6.5.6, details & quotes here). So you can get any result out of this.

Furthermore, a null pointer is not guaranteed to have the binary representation zero in C. I'd recommend studying What's the difference between null pointers and NULL?.

And then finally, %p gives the output in hex. The basics of pointer arithmetic is that typeptr + 5 equals adding sizeof(*typeptr) * 5, expressed in bytes. Since sizeof(int) is likely 0x4, you get 0x4 * 0x5 = 0x14.

Upvotes: 0

W&#246;r Du Schnaffzig
W&#246;r Du Schnaffzig

Reputation: 1051

The answer is in the comments. In your case sizeof(int) == 4 and therefore numPtr + 2 points to address 8 = 2*4 and numPtr + 5 points to address 20 = 5*4, which is indeed 0x14 in hexadecimal representation.

Upvotes: 0

Related Questions