5

Consider the following in C

int arr[]= {1,2,3,4,5};

My system uses 4 bytes to store int data. Now &arr[0] => 0022FEB0 and &arr[1]=>0022FEB4 at a moment of run

Now

int diff=&arr[1]-&arr[0];

Value stored in diff is 1 and not 4.

Why?

klutt
  • 25,535
  • 14
  • 43
  • 72
Abhishek Ghosh
  • 319
  • 2
  • 11
  • 1
    Pointer arithmetic works the same way as array indexing. You don't index an `int` array by `0`, `4`, `8` etc. The work is done for you by the compiler. In your example the difference between pointers is the same as the difference in the array indices. – Weather Vane Jun 17 '18 at 17:28
  • 1
    Unclear how that "hack" would let you find the size of an array. – juanchopanza Jun 17 '18 at 17:28
  • Which language — C or C++? They're different. Don't dual-tag questions. – Jonathan Leffler Jun 17 '18 at 17:30
  • 1
    To get the difference in bytes, you could do `int diff=(char*)&arr[1] - (char*)&arr[0];`, if that's what you are trying to do. – Eljay Jun 17 '18 at 17:32

6 Answers6

6

That's the way pointers work. You are not calculating the byte difference. You're calculating the difference in number of elements.

To get the element size, use sizeof(*arr)

To get the byte difference, use (&arr[1]-&arr[0]) * sizeof(*arr)

klutt
  • 25,535
  • 14
  • 43
  • 72
3

I think that what you want it this:

int diff = (&arr[1]-&arr[0]) * sizeof(int);

When you tells to compiler the data type you are working with, it will consider it in the arithmetic.

2

You are not calculating the byte difference. To calculate byte difference there is already an answer on StackOverflow. here is a link to answer Getting the difference between two memory addresses

Ammar Ali
  • 692
  • 5
  • 18
1

The compiler knows that types of substracted ones whose are pointer to int.

#include <stdio.h>
#include <stddef.h>

int main(void) {

    int arr[]= {1,2,3,4,5};

    /*
    int diff=&arr[1]-&arr[0];

    In your system, there's a 4 byte difference in memory, so you'd get diff = 1
    here because the compiler knows they're ints so the result is diff/sizeof(int)
    */

    uintptr_t firstNumAddress  = (uintptr_t)&arr[0];
    uintptr_t secondNumAddress = (uintptr_t)&arr[1];

    ptrdiff_t ptrDiff = secondNumAddress - firstNumAddress;
    printf("%lu - %lu = %ti\n", secondNumAddress, firstNumAddress, ptrDiff);

    return 0;
}
snr
  • 13,515
  • 2
  • 48
  • 77
1

You are doing pointer arithmetic, instead of integer arithmetic.

To do integer arithmetics, just cast the addresses to an integer type of the same size in bytes of a pointer (in 32-bit systems, that can be 4 bytes; in 64-bit, that can be 8 bytes).

For example, in C, just do:

int diff = (uintptr_t) &arr[1] - (uintptr_t) &arr[0];

And you get the difference in bytes.

Enzo Nakamura
  • 117
  • 1
  • 9
  • 2
    It is intended that the result of converting a pointer to an integer be unsurprising, but the specific result is not required by the C standard, and some C implementations might not produce a simple memory address from this conversion, in which case subtracting two such results of conversions may not produce the difference in bytes. Additionally, the preferred type for such operations would be `uintptr_t` rather than `long`. – Eric Postpischil Jun 17 '18 at 17:47
  • 1
    If pointers are wider then a `long` this won't work. – alk Jun 17 '18 at 18:06
  • @alk: Yes, that's why I mentioned to use an integer type of the same size of the pointer. Anyway, I will switch `long` to `uintptr_t` in the example, to avoid any kind of trouble. Thanks, alk and Eric. – Enzo Nakamura Jun 17 '18 at 19:02
-1

that's same with
int diff =(*)(a+1-0)
it is code's source to produce the result.

許維德
  • 109
  • 1
  • 9