# What is the difference between an index and an offset?

I am looking to understand the difference between the words index and offset. I have never seen "offset" in reference to lists/arrays/etc in programming. I have only seen index.

To me, these mean the same thing. But how one is used heavily and one never implies they have different meanings. They might also just have historical or mathematical significance I'm not seeing.

Using the code snippet as a reference:

``````x = arr[0];
y = arr[2];
``````

all the below statements are true:

• `x` has an index of zero
• `x` is offset from the beginning of the array by zero
• `y` has an index of 2
• `y` is offset from the beginning of the array by 2

This really makes it look like index and offset mean the same thing.

• Offset is relative. You can have an offset relative to an index for example. But offset relative to the beginning of the array is the same as index Nov 11, 2020 at 10:23

An index stands alone, though some data structure (e.g. array) is implied in using the index.  Still the index can be used (e.g. as an id) without an array.

An offset has to be an offset from something, so the difference is in the degree with which another entity is implied.  `s[105]` is offset by `5` from `s[100]` (e.g. we may have a substring at 100-105).  Here the value `5` does not really stand alone, whereas indexes `100` and `105` do stand alone (to a larger degree, at least).

Index is often used with arrays whose element size is fixed, and indexes are implicitly scaled by that size constant (in most languages but not assembly) to access an array element.

Offset is often used with variable sized items, e.g. fields at different offsets from the beginning of a struct, record or class object.  Because fields are each potentially of different size, we would not index (scale by some fixed size) into a struct to get different fields, but we would "offset" from the beginning of the struct to get a particular field.

• In other words: an index is absolute, an offset is relative (to some other position). All examples given so far use arrays or structs or memory but you can also look at graphics. A point has an absolute position which is only relative to its origin, say (5, 2). We can add an offset of (-1, 3) to that point to get to position (4, 5). An index is a pointer (think index finger), an offset is a shift. Nov 11, 2020 at 7:06
• a good example would be explaining the difference between looping over an array by index and paginating a collection of an undefined number of elments.
– Laiv
Nov 11, 2020 at 14:57

An offset is a displacement you add to a position. If you are talking about the position in a list or an array, and the offset is from the beginning. Then yes, in that context, the offset is the index in refers to.

Instead, you could be talking about an offset from a given position on the array (from the end, for example). Then the offset would not match the index it refers to. You need to add the offset to the starting position from where you measure it (which is an index). When you count from the beginning, the index you add to the offset is 0.

You could also talk about offsets of position in memory. These offsets you add to a base address. For example, your array would have a base address. To that address you add an offset (multiplied by the size of an element) to find the position in memory of an index. For a counter example, you can also talk of the index of an element in a linked list. That element would be a node, which has a position in in memory. You do not find the positions other elements by adding the index to the position of the first element.

Staying with offsets of position in memory, we could be talking of a struct/record. Each member field of the struct/record has a position offset from the base address of it. You add that offset to find the position of the member field. Keep in mind that the size of each member field could be different.

And we could not be talking about a position in a list or array at all. If we are talking about positions on the screen, or in 3D virtual space, or whatever. In those situations, the positions are vectors. And so offsets are a vectors too. An offset would represent a translation transformation in whatever space you are working.

To summarize, indexes are discrete (integer), and count from the beginning. An offset is a position displacement. Offset can be discrete or "continuous" (floating point), and from any position you want.

It happens that an offset from the beginning of an array, corresponds to the same index of the array.

No. They never mean the same thing. Even when they're both, say 2, they don't mean the same thing.

Oh sure, you can index and offset by simply adding but we use these words for a reason.

• Offset means start here from now on.
• Index means here's that thing you wanted.

Sure they can both be a 2 that you add but the meaning of that 2 is very different.

As proof here's some code.

``````for (int index = offset; index < size; index++) {
sum += arr[index];
}

for (int offset = index; offset < size; offset++) {
sum += arr[offset];
}
``````

Both values start out the same. The code will perform identically. Yet... well my disgust for the second one should need no explanation. Bleh.

They often work out to be the same, but conceptually they are different. An index is picking a particular numbered thing out of an array or other structure. An offset is starting at one point, moving by the offset, and seeing where you now are.

Consider the C code:

``````int a[10];
int x = a[5];
int y = *(a + 5);
``````

Here x is calculated using an index, while y uses an offset from the start of the array.

Here's an example of using indexes and offsets when working with a matrix data structure. Hopefully the abundance of comments helps illustrate the conceptual difference.

``````size_t nVectors = 100; // Per matrix
size_t nElements = 50; // Per vector
size_t matrixSize = nVectors * nElements;

// A 2d array with "flat" storage.
// Conceptually thought of as a list of vectors.
double *matrix = new double[matrixSize];

// For each vector
// Index points to vectors in the figurative list of vectors
for (size_t vectorIndex = 0; vectorIndex < nVectors; ++vectorIndex) {
// Offset of this vector from the start of the matrix
// Offset relative to `matrix`
size_t vectorOffset = vectorIndex * nElements;

// For each element of this vector
// Index points to elements of the figurative vector
for (size_t elementIndex = 0; elementIndex < nElements; ++elementIndex) {

// Offset of this element from the start of the matrix
// Offset relative to `matrix`
size_t elementOffset = vectorOffset + elementIndex;

// Use elementOffset as an index into the matrix
matrix[elementOffset] = 1;

// Though this is more commonly shown inline
matrix[vectorOffset + elementIndex] = 1;

// Same thing but dreadfully obscure
// Illistrates jumping vectorOffset into the matrix
// and from there indexing into the vector with elementIndex
(matrix + vectorOffset)[elementIndex] = 1;
}
}

//
// Alternative way to write these loops.
// There are reasons outside the scope of this question that this approach might be discouraged.
// (Aliasing, wouldn't work with std::vector, etc.)

for (size_t vectorIndex = 0; vectorIndex < nVectors; ++vectorIndex) {
// vector is vectorOffset into matrix
// Index into the figurative list of vectors with vectorIndex
// As if: vector = vectorList[vectorIndex]
double *vector = matrix + vectorIndex * nElements;

for (size_t elementIndex = 0; elementIndex < nElements; ++elementIndex) {
// Index into the current vector
vector[elementIndex] = 1;

// Did not think about `matrix`, vectorOffset, or elementOffset when
// selecting the element.
}
}

//
//
delete[] matrix;
``````

Stop and think about the state at a point:

• vectorIndex = 2;
• elementIndex = 4;

Yields:

• vectorOffset = 2 * 50 = 100;
• elementOffset = 100 + 4 = 104;

(nVectors, nElements) is often written as (cols, rows) or (width, height) with (vectorIndex, elementIndex) being (col, row) or (x, y). I prefer to avoid the other terms because they are less clear to me and I can sidestep the major dimension question.

In addition to the examples presented, indexes need not have an actual array under them. In memory they almost certainly do, but on disk they likely do not because of the high update cost that would entail.

For example, consider indexes on fields in a SQL database. There's chunks of data in the database but a large index isn't going to just sit there in one block.

Fundamentally, index is the concept, offset is how it is normally implemented in memory.

There's a lot of good answers so I'll just cover something they didn't explicitly. I'm talking about the case of an array of fixed size elements. If the elements are four bytes long, the offset and index of the first are both zero. The index of the second one is 1, but the offset is four bytes. Advancing the index by 1 increases the offset by the size of one element.

``````#include <iostream>

int main()
{
int array[10]; // we assume four byte/32 bit integers for simplicity
// Addresses of ints at index 1 and index 0
std::cout << &array[1] << '\n';
std::cout << &array[0] << '\n';
// This is the offset to the element at index [1]
std::cout << (char*)(&array[1]) - (char*)(&array[0]) << '\n';
}
``````