Concepts / STL containers and the handle-to-elements model

STL containers and the handle-to-elements model

An array is a fixed-size sequence of elements of a single given type, with the number of elements specified at compile time.

  • Programming

Testing a Common Belief About Arrays

Many programmers first meet arrays as a list of values written in a row. Once they understand one kind of array, they often assume every array works the same way. A common version of this belief goes like this: an array is simply a built-in array with a new name, so whatever is true of a built-in array must also be true of an array. This article tests that belief. The short answer is that the two are close, but not close enough to rely on without understanding the details.

What do you think happens?

Think about what a built-in array does when it is used inside an expression. Does an array do the same thing? Make a prediction before reading on.

Reveal answer
Answer:

An array avoids the implicit, potentially surprising conversions to pointer types that a built-in array can undergo.

A built-in array can quietly change into something else when it is used in an expression. An array is designed to be more predictable and avoids these implicit conversions. This is one of the reasons the belief that the two are identical does not hold up.

Reading the Definition Phrase by Phrase

Definition

An array is a fixed-size sequence of elements of a single given type, with the number of elements specified at compile time.

Each part of that definition carries a specific meaning. Read it as three ideas held together. Sequence means the elements are arranged in an order. Of a given type means every element in one array has the same type. Fixed-size means the number of elements does not change while the program runs, and that number is set when the program is compiled rather than when it runs.

sequenceelements arranged in anorderof a given typeevery element has the sametypefixed-sizecount set at compile timecombined withcombined with
Each phrase of the definition contributes one property: order, a single shared type, and a count that is fixed at compile time.

Put together, these three ideas describe a container whose capacity is decided in advance. The array holds a run of elements of one type, and its capacity neither grows nor shrinks afterward.

Where an Array's Elements Live

Because the size is fixed at compile time, the elements of an array can be placed in several kinds of storage. An array can be allocated with its elements on the stack, inside an object, or in static storage. The choice depends on where the array is declared, because the elements are allocated in the scope where the array is defined.

A scope is the region of code in which a name is visible. An array declared inside a function lives within that function's scope. An array declared at a broader level lives in that broader scope. So when you ask where an array's elements are, the first question to answer is where the array was declared.

Worked example

Tracing where the elements of one array are placed

A function declares an array of four temperature readings, all of one given type, with the count written directly into the declaration. Where are its elements allocated, and what determines that location?

  1. 1
    Identify the element type

    All four readings share a single given type, so every element is the same kind of value.

  2. 2
    Identify the element count

    The count of four is fixed when the program is compiled. It cannot change while the function runs.

  3. 3
    Locate the declaration

    The array is declared inside the function, so its scope is that function's scope.

  4. 4
    Choose the storage

    Because the array is declared inside a function, its elements are allocated in that function's scope. Storage depends on where the declaration sits, which is the scope where the array is defined.

Result

The four elements are allocated in the scope where the array is declared, which here is the function. Their count and type are settled before the program runs.

Built-in Arrays Versus Arrays With Their Size Attached

Now the original belief can be corrected. An array is best understood as a built-in array with its size firmly attached. In a built-in array, the element type and the number of elements are not carried together as one thing. An array keeps them together as one unit. The core idea of holding a fixed run of elements is the same in both, but the array is designed to be more predictable.

element typetracked separatelyelement type andcounttravel together as one unitelement counttracked separatelyseparate
The built-in array tracks its element type and element count separately, while the array keeps both together as a single unit.
PropertyBuilt-in arrayArray
Core idea of a fixed run of elementsPresentPresent, the same idea
Element type and countNot carried together as one unitTravel together as one unit
Implicit conversion to pointer typesCan occur in expressionsAvoided
Convenience functionsNot offeredA few are provided
Overhead in time or spaceBaselineNone compared with a built-in array

How a built-in array and an array differ according to the source material

Direct Containment Versus the Handle-to-Elements Model

A second distinction separates an array from the STL containers. STL containers follow a handle-to-elements model. The container refers to its elements rather than holding them in the same direct way. An array does not follow that model. An array directly contains its elements, so the array is the owner of its elements. An STL container works through handles that refer to the elements it manages.

arrayowns its elementselementsstored directly insideSTL containermanages its elementshandlesrefer to elementselementsreached through handlesdirectly containsholdsrefers to
On the array side the elements sit inside the array itself. On the STL side the container reaches its elements through handles.

Mistakes When Comparing Arrays and Containers

  • Common mistake

    Assuming an array is just a built-in array with a new name.

    Why it fails

    An array keeps its element type and element count together as one unit and avoids implicit conversions to pointer types that a built-in array can undergo.

    Do this instead

    Treat an array as a built-in array with its size firmly attached, and check what the array does in expressions rather than assuming it behaves identically.

  • Common mistake

    Thinking the size of an array can grow or shrink while the program runs.

    Why it fails

    The size is fixed and is specified at compile time, so the capacity is decided in advance.

    Do this instead

    Hold the size as a fixed property decided before the program runs, and design around a capacity that does not change.

  • Common mistake

    Believing an array's elements always live in the same place regardless of where it is declared.

    Why it fails

    The elements are allocated in the scope where the array is defined, and they can sit on the stack, inside an object, or in static storage.

    Do this instead

    Identify the declaration's scope first, then reason about where its elements are placed.

  • Common mistake

    Treating an STL container and an array as owning their elements in the same way.

    Why it fails

    An array directly contains its elements, while an STL container refers to its elements through the handle-to-elements model.

    Do this instead

    When comparing the two, focus on ownership: the array owns its elements directly, and the container works through handles.

  • Common mistake

    Assuming extra predictability has a performance price. The source states there is no overhead in time or space compared with a built-in array.

Checking Your Understanding

MEDIUM

An array is declared with a fixed count and a single element type. Explain, in your own words, which property of the array is decided at compile time, and why that matters for how many elements it can hold. Then state whether an STL container and an array differ in who owns the elements, and describe the difference in one sentence.

Hints
  • Recall the three ideas in the definition: sequence, a given type, and fixed size.
  • Think about whether the count can change while the program runs.
  • Compare direct containment with the handle-to-elements model.

Key Points to Carry Forward

  1. 1
    An array is a fixed-size sequence of elements of a single given type, and its number of elements is specified at compile time.
  2. 2
    An array is best understood as a built-in array with its size attached, and it avoids implicit conversions to pointer types.
  3. 3
    The elements of an array are allocated in the scope where the array is defined, on the stack, inside an object, or in static storage.
  4. 4
    An array directly contains its elements, while STL containers follow the handle-to-elements model, referring to elements through handles.
  5. 5
    Using an array adds no overhead in time or space compared with a built-in array.

Key Takeaways

  • An array is a fixed-size sequence of elements of a single given type, with its element count specified at compile time.
  • An array is best understood as a built-in array with its size attached, avoiding implicit conversions to pointer types.
  • An array directly contains its elements, whereas STL containers follow the handle-to-elements model and reach elements through handles.
  • Array elements are allocated in the scope where the array is defined, and there is no time or space overhead compared with a built-in array.

Related concepts

More concepts starting with S