Row-major array index calculator
In a 3 × 4 × 5 array of 8-byte elements, position 1, 2, 3 is element 33, byte offset 264, address 4360 from a base of 4096. Each stride and contribution is shown, so you can check pointer arithmetic or debug a flattened buffer. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Dimensions
- 3, 4, 5
- Indices
- 1, 2, 3
- Element size bytes
- 8
- Base address
- 4,096
- Order
- row-major
- Strides
- 20, 5, 1
- Contributions
- 20, 10, 3
- Linear index
- 33
The row-major array index calculator converts coordinates in a multidimensional array into the single linear position used by C-style contiguous memory layouts. Provide each dimension from outermost to innermost, the matching zero-based index for every axis, an element size in bytes, and an optional base address. The result shows the stride of every axis, each index contribution, the final element offset, its byte offset, and the resulting byte address. It is useful for checking pointer arithmetic, debugging flattened buffers, and explaining how nested array coordinates map onto memory.
Enter dimensions and indices in matching axis order
List the dimension sizes from the outermost axis to the innermost axis, exactly as they appear in a declaration or shape. For an array shaped as three planes, four rows, and five columns, enter dimensions of 3, 4, and 5. Then provide one zero-based index for each dimension in the same order.
The coordinate for the second plane, third row, and fourth column is therefore 1, 2, and 3. Dimension sizes must be positive integers, while every index must be at least zero and strictly smaller than its corresponding dimension. The calculator rejects mismatched ranks and out-of-bounds coordinates instead of silently producing an address outside the array.
Element size is also required because an element index alone does not identify a byte location. Use the actual storage width of one element, such as four bytes for a typical 32-bit integer or eight bytes for a typical double. If you know where the array begins in memory, provide that nonnegative base address; otherwise leave it at the default of zero and interpret the result as an offset from the array start.
Understand the row-major stride calculation
Row-major ordering stores the last axis contiguously, so moving one position along that axis advances by exactly one element. Its stride is therefore one. The stride of every earlier axis is the product of all dimension sizes to its right.
With dimensions 3 by 4 by 5, the strides are 20, 5, and 1: advancing one plane skips four rows of five elements, advancing one row skips five elements, and advancing one column skips one. The calculator multiplies each index by the stride for its axis and exposes those products as contributions. Adding the contributions produces the zero-based linear index.
For coordinates 1, 2, and 3, the calculation is 1 times 20, plus 2 times 5, plus 3 times 1, giving element index 33. Showing intermediate values makes the result auditable and helps reveal a common mistake: using column-major multipliers or reversing the dimensions. The algorithm performs checked integer arithmetic throughout.
If a product or sum would exceed JavaScript's safe integer range, it returns an input error rather than presenting a rounded memory location as exact.
Turn the element index into a byte address
A linear index counts elements, not bytes. To obtain the byte offset, multiply the linear index by the element size. An element index of 33 with eight-byte elements begins 264 bytes after the start of the array.
The final byte address is that offset added to the supplied base address. If the base address is 4096, the element begins at byte address 4360. The response keeps the linear index, byte offset, base address, and byte address separate so each stage can be compared with source code, a debugger, a binary format specification, or a GPU buffer calculation.
The address is returned as an ordinary decimal integer and is intended for exact arithmetic within the safe integer range; it does not dereference memory or inspect a running process. The calculation assumes a dense contiguous array with no padding between elements or rows. If a library uses pitched rows, explicit leading dimensions, sliced views, or custom strides, its physical layout is not described solely by shape and this calculator should not replace those stride values.
What you can do with it
Check pointer arithmetic
Confirm the element and byte offsets used in C, C++, Rust, or WebAssembly code before dereferencing a flattened buffer.
Debug tensor flattening
Compare expected row-major strides and contributions with a tensor library, serializer, or data interchange routine.
Teach memory layout
Show how each multidimensional coordinate contributes to a single contiguous position and final address.
FAQ
Are indices zero-based?
Yes. Every index starts at zero and must be smaller than the corresponding dimension size.
What is row-major ordering?
It is a contiguous layout where the last array axis changes fastest, as in standard C-style multidimensional arrays.
What should I use for the base address?
Use the byte address where the array begins. Leave it at zero when you only need an offset relative to the array start.
Does this handle column-major arrays?
No. The calculation deliberately implements row-major ordering. Column-major storage uses a different stride sequence.
Does it account for row padding or custom strides?
No. It assumes dense contiguous elements. Pitched, padded, transposed, or sliced storage requires the actual physical strides.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev/array-rowmajor-index \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"dimensions":[3,4,5],"indices":[1,2,3],"element_size_bytes":8}'const res = await fetch("https://api.kit.forhosting.com/dev/array-rowmajor-index", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"dimensions": [
3,
4,
5
],
"indices": [
1,
2,
3
],
"element_size_bytes": 8
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/array-rowmajor-index",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"dimensions": [
3,
4,
5
],
"indices": [
1,
2,
3
],
"element_size_bytes": 8
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/array-rowmajor-index", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"dimensions":[3,4,5],"indices":[1,2,3],"element_size_bytes":8}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"dimensions":[3,4,5],"indices":[1,2,3],"element_size_bytes":8}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/array-rowmajor-index", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"dimensions": [
3,
4,
5
],
"indices": [
1,
2,
3
],
"element_size_bytes": 8
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.array_rowmajor_index",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_dimensions | 32 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Turn the element index into a byte address
Each API request costs $0.002, while the same deterministic computation can run in the browser for quick checks.
Technical questions
What does it cost through the API?
Each request costs $0.002. The browser version performs the same deterministic calculation locally.