Learning Objectives – after this chapter you will be able to:
  • Declare fixed-size and dynamic arrays correctly.
  • Use length, push, pop, delete and index access.
  • Create memory arrays and use calldata array slices.
  • Remove an element efficiently and avoid out-of-bounds errors.
Array
  • An array stores a collection of elements of the same data type; each element has a position called its index.
  • Instead of creating many separate variables of the same type, we declare one array and access each element by index.
  • Indexes start at 0: the first element is arr[0] and the last is arr[arr.length - 1].
  • In Solidity an array can be fixed-size or dynamic, and it can be kept in storage, memory or calldata.
Fixed-size Arrays

The size is part of the type and is set when the array is declared; the number of elements can never exceed it.

<data type>[size] <array name> = <initialisation>;
uint[5] public marks = [70, 85, 90, 65, 88];
Dynamic Arrays

The size is not fixed when declared; storage dynamic arrays grow and shrink at run time with push and pop.

<data type>[] <array name> = <initialisation>;
uint[] public scores = [10, 20, 30];
Array Operations
OperationSyntaxNotes
Access an elementarr[i], arr[i] = vIndex ≥ length reverts (Panic error)
Length of arrayarr.lengthNumber of elements
Pusharr.push(v)Adds to the end – storage dynamic arrays only
Poparr.pop()Removes the last element; reverts on an empty array
Delete an elementdelete arr[i]Resets it to the default value – the length does not change
Memory arrayuint[] memory a = new uint[](n);Length fixed after creation; no push/pop
Array slicedata[start:end]Only for calldata arrays
Removing an element without leaving a gap

Copy the last element into the position to remove, then pop(). This is cheap but changes the order of elements. Shifting every element left keeps the order but costs gas for every move.

Example : Array Operations
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract ArrayDemo {
    uint[5] public fixedMarks = [70, 85, 90, 65, 88];   // fixed-size
    uint[] public scores;                                // dynamic

    function addScore(uint s) external {
        scores.push(s);                 // grows by one
    }

    function removeLast() external {
        scores.pop();                   // reverts if empty
    }

    function count() external view returns (uint) {
        return scores.length;
    }

    // remove index i by moving the last element into its place
    function removeAt(uint i) external {
        require(i < scores.length, "Index out of range");
        scores[i] = scores[scores.length - 1];
        scores.pop();
    }

    function getAll() external view returns (uint[] memory) {
        return scores;                  // returns a memory copy of the whole array
    }

    function squares(uint n) external pure returns (uint[] memory result) {
        result = new uint[](n);         // memory array, length fixed at n
        for (uint i = 0; i < n; i++) {
            result[i] = i * i;
        }
    }

    function firstTwo(uint[] calldata data) external pure returns (uint[] memory) {
        return data[0:2];               // array slice (calldata only)
    }
}

Note: for a public array the automatic getter takes an index, e.g. scores(0); use a function such as getAll() to return the whole array.

Key Takeaways
  • Fixed: T[size]; dynamic: T[]. Indexes start at 0.
  • push/pop work only on storage dynamic arrays; memory arrays have a fixed length after new.
  • delete arr[i] resets a value but keeps the length; swap-and-pop removes it.
Download | Print      E-Notes

The PDF E-Notes are the earlier printable version of this chapter. The notes on this page are the latest, revised version.

Question / Answer (15 questions)

Answer : An array is a collection of elements of the same data type stored in order, where each element is accessed by an index starting from 0.

Answer : Fixed-size arrays: <type>[size] name; e.g. uint[5] marks;. Dynamic arrays: <type>[] name; e.g. uint[] scores;.

Answer : arr.length - 1, because indexing starts at 0.

Answer : push(v) appends an element to the end and increases the length by one. It can be used only on dynamic arrays stored in storage (and on storage bytes).

Answer : pop() removes the last element and reduces the length by one. Calling it on an empty array reverts the transaction.

Answer : It resets the element at index i to its default value (e.g. 0) but does not shrink the array or change its length.

Answer : Copy the last element into the index to be removed and then call pop(). This is gas-efficient but changes the order of elements.

Answer : With the new keyword: uint[] memory a = new uint[](n);. Its length is fixed once created, so push and pop are not available.

Answer : A slice x[start:end] is a view of part of an array, from start up to (not including) end. Slices are currently supported only for calldata arrays.

Answer : The access reverts with a Panic error (array out of bounds); Solidity checks array indexes automatically.

Answer : It takes an index and returns a single element, e.g. scores(0). To return the whole array, write a function returning uint[] memory.

Answer : Its length is always 5; the size of a fixed-size array cannot change.

Answer : Copying a large storage array into memory consumes a lot of gas; if it exceeds the gas cap the call fails, so large datasets should be paged or read off-chain.

Answer : uint total; for (uint i = 0; i < scores.length; i++) { total += scores[i]; }

Answer : By adding more brackets, e.g. uint[][] grid; or uint[3][2] table;. Note that uint[3][2] is two arrays of three elements each (the notation is reversed compared with some other languages).
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. Which declaration creates a FIXED-size array of 5 unsigned integers?

Show Answer

Correct Answer : C. uint[5] a;
Solidity places the size in the type: uint[5].

Q2. After delete arr[1] on a 4-element uint array, the length is:

Show Answer

Correct Answer : A. 4
delete resets the value but keeps the length.

Q3. Which operation is NOT available on a memory array created with new?

Show Answer

Correct Answer : D. arr.push(x)
Memory arrays have a fixed length after creation.

Q4. Array slices like data[0:2] are supported for:

Show Answer

Correct Answer : A. calldata arrays
Slices currently work only with calldata.

Q5. Accessing arr[arr.length] will:

Show Answer

Correct Answer : B. Revert with a Panic error
Out-of-bounds access is checked and reverts.

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Solidity Team. (n.d.). Types (value types, reference types, mappings, operators, conversions). Solidity Documentation. https://docs.soliditylang.org/en/latest/types.html
  2. Solidity Team. (n.d.). Expressions and Control Structures (if/else, loops, checked arithmetic, error handling, try/catch). Solidity Documentation. https://docs.soliditylang.org/en/latest/control-structures.html
  3. Solidity Team. (n.d.). Cheatsheet. Solidity Documentation. https://docs.soliditylang.org/en/latest/cheatsheet.html
  4. GeeksforGeeks. (n.d.). Solidity – Arrays. https://www.geeksforgeeks.org/solidity-arrays/
  5. Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.