1

I'm trying to find the stride between the index [0][0] and [0][1], as well as between [0][0] and [1][0] to try and understand how it works, so I'm printing out the memory address of each of them and then getting the difference, which is what I understand stride to be.

I.e.: the memory address at [0][0] is 0x00E8C140 and the memory address at [0][1] is 0x00E8C148, so the stride should be 8, right? (Array is 2D array size [1000][1000])

for (int y = 0; y < 1000; ++y)
{
    for (int x = 0; x < 1000; ++x)
    {
        Array[y][x] = (x == y) ? 1.0 : 0.0;
        if (y == 0 && x == 0) {
            printf("&Array[%d][%d]=%p\n",y, x, &Array[y][x]);
        }
        if (y == 0 && x == 1) {
            printf("&Array[%d][%d]=%p\n",y, x, &Array[y][x]);
        }
        if (y == 1 && x == 0) {
            printf("&Array[%d][%d]=%p\n", y, x, &Array[y][x]);
        }
    }
}

Output:

&Array[0][0]=00E8C140
&Array[0][1]=00E8C148
&Array[1][0]=00E8E080

I mean it makes sense to me, but I'm not really even sure if I'm actually printing the memory address correctly, because it's such a large number. I'd have thought the base address ([0][0]) would be like 1000 or something.

Kevin
  • 16,549
  • 8
  • 60
  • 74
  • 1
    Don't worry about the large addresses, due to [ASLR](https://en.wikipedia.org/wiki/Address_space_layout_randomization) things can end up almost anywhere. – Mark Ransom Oct 17 '19 at 02:38

1 Answers1

2

The difference between array[0][1] and array[0][0] is one array element. The size of the difference is whatever the size of the array element is. So for an array containing char the difference will be 1 and for an array containing long it will be 8 on a 64 bit machine.

The difference between array[1][0] and array[0][0] is however many array elements are in a row (for an array of 1000 x 1000 it will be 1000 array elements). The size of the difference is whatever the size of the array element is multiplied by the number of array elements that are in a row. So for an array of 1000 x 1000 containing char the difference will be 1 x 1000 and for the same size array containing long it will be 8 x 1000 on a 64 bit machine.

Here is an example program that uses 10 x 10 arrays:

#include <stdio.h>

int main()
{
    #define ARRAY_WIDTH 10
    #define ARRAY_HEIGHT 10
    char CArray[ARRAY_HEIGHT][ARRAY_WIDTH];
    short SArray[ARRAY_HEIGHT][ARRAY_WIDTH];
    long LArray[ARRAY_HEIGHT][ARRAY_WIDTH];

    printf("&CArray[0][1] - &CArray[0][0] = %ld (%p-%p)  sizeof(char) = %lu\n",
            (long)(&CArray[0][1]) - (long)(&CArray[0][0]), &CArray[0][1], &CArray[0][0], sizeof(char));
    printf("&SArray[0][1] - &SArray[0][0] = %ld (%p-%p)  sizeof(short) = %lu\n",
            (long)(&SArray[0][1]) - (long)(&SArray[0][0]), &SArray[0][1], &SArray[0][0], sizeof(short));
    printf("&LArray[0][1] - &LArray[0][0] = %ld (%p-%p)  sizeof(long) = %lu\n",
            (long)(&LArray[0][1]) - (long)(&LArray[0][0]), &LArray[0][1], &LArray[0][0], sizeof(long));

    printf("&CArray[1][0] - &CArray[0][0] = %ld (%p-%p)  sizeof(char) * ARRAY_WIDTH = %lu\n",
            (long)(&CArray[1][0]) - (long)(&CArray[0][0]), &CArray[1][0], &CArray[0][0], sizeof(char) * ARRAY_WIDTH);
    printf("&SArray[1][0] - &SArray[0][0] = %ld (%p-%p)  sizeof(short) * ARRAY_WIDTH = %lu\n",
            (long)(&SArray[1][0]) - (long)(&SArray[0][0]), &SArray[1][0], &SArray[0][0], sizeof(short) * ARRAY_WIDTH);
    printf("&LArray[1][0] - &LArray[0][0] = %ld (%p-%p)  sizeof(long) * ARRAY_WIDTH = %lu\n",
            (long)(&LArray[1][0]) - (long)(&LArray[0][0]), &LArray[1][0], &LArray[0][0], sizeof(long) * ARRAY_WIDTH);

    return 0;
}

This program produces the following output (remember my arrays are only 10 x 10):

&CArray[0][1] - &CArray[0][0] = 1 (0x7ffcff4045e1-0x7ffcff4045e0)  sizeof(char) = 1                                                           
&SArray[0][1] - &SArray[0][0] = 2 (0x7ffcff404652-0x7ffcff404650)  sizeof(short) = 2                                                          
&LArray[0][1] - &LArray[0][0] = 8 (0x7ffcff404728-0x7ffcff404720)  sizeof(long) = 8                                                           
&CArray[1][0] - &CArray[0][0] = 10 (0x7ffcff4045ea-0x7ffcff4045e0)  sizeof(char) * ARRAY_WIDTH = 10                                           
&SArray[1][0] - &SArray[0][0] = 20 (0x7ffcff404664-0x7ffcff404650)  sizeof(short) * ARRAY_WIDTH = 20                                          
&LArray[1][0] - &LArray[0][0] = 80 (0x7ffcff404770-0x7ffcff404720)  sizeof(long) * ARRAY_WIDTH = 80                                           

Have a look here: https://onlinegdb.com/BJwpNDBYB

Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
  • You do explain what the difference between `array[0][1] and array[0][0]` is, but it may also be worth pointing out that the difference between adjacent elements isn't a *stride*, it's just `sizeof (an_element)`; Moreover, the *stride* is generally an abstraction that allows treating elements of a 1D array as if it were a 2D array. (that's more in the noise, but relevant to an understanding of terminology) – David C. Rankin Oct 17 '19 at 04:19
  • @DavidC.Rankin I intentionally didn't use "stride" in my answer at all to avoid confusing the issue. The reason it is confusing to me is that https://en.wikipedia.org/wiki/Stride_of_an_array says the stride is the number of memory locations between adjacent array elements and that if there is no padding between elements the stride is the same as the size of an array element. So that implies to me that a stride *is* defined to be the difference between adjacent array elements. But, like you, it's not how I understood stride. Do you have a suggestion for how to explain stride properly? – Jerry Jeremiah Oct 17 '19 at 04:26
  • Yes, it gets murky, and then you have the use of `stide/stripe` from a RAID array standpoint as well. The answer was fine, and your choice was probably a good one considering. – David C. Rankin Oct 17 '19 at 04:40