LongCut logo

STL std::array (Since C++11) | Modern Cpp Series Ep. 114

By Mike Shah

Summary

## Key takeaways - **std::array offers better type safety than C-style arrays**: Unlike C-style arrays, std::array leverages templates to store the array's size with the array itself, leading to improved type safety and preventing accidental decay into pointers. [00:53] - **C-style arrays decay to pointers in functions**: When C-style arrays are passed into functions, they decay into pointers, causing `sizeof` to report the size of a pointer (typically 8 bytes) instead of the array's actual size, which can be a source of confusion. [04:34] - **std::array carries size information, avoiding pointer decay**: std::array, as a class, inherently carries its size information, meaning it does not decay to a pointer when passed to functions, thus preserving its actual size and preventing common errors. [06:39] - **Template nature of std::array enforces compile-time size checks**: Because std::array is templated with its size, attempting to use an array of one size where another is expected will result in a compile-time error, catching potential issues early. [10:44] - **std::array provides bounds checking with .at()**: The `.at()` member function of std::array performs bounds checking, throwing an exception if an out-of-bounds index is accessed, offering a safer alternative to the subscript operator which may not always perform checks. [14:11] - **Access underlying C-style array data with .data()**: If you need to interface with legacy C code or require a raw pointer to the array's data, std::array provides a `.data()` member function that returns a pointer to the beginning of the array's elements. [18:14]

Topics Covered

  • Why C-style arrays lose size information when passed.
  • Standard array solves array decay with type and size.
  • Achieve safer C++ arrays with compile-time bounds checking.
  • Unlock powerful algorithms with C++ standard arrays.
  • Seamlessly bridge modern C++ arrays with legacy C code.

Full Transcript

hey what's going on folks it's Mike here

and welcome to the modern C plus plus

Series in this lesson we're going to

continue talking about the standard

template library and specifically

talking about standard array now we've

talked about this very briefly if you've

been following this series for quite

some time but now we're going to do a

little bit more of a deep dive into

understanding how arrays are and how

they fit into the standard template

library and why we might want to prefer

them versus Raw C style race so with

that said let's go ahead and dive in

here so let's just go ahead and start

from CPP reference and where we're going

to venture is in the containers Library

so if I zoom in here a little bit you'll

see that arrays the first thing and it's

something that came in C plus 11. now of

course arrays are not a new thing

they're available in pretty much every

programming language as far as I know

um or at least every C C plus plus and

these style systems languages but what C

plus plus 11 gives us is a new special

style of array that's a little bit safer

and better to use but in order to

understand this before we dive in let's

just go ahead and take a look at regular

C Style arrays and where the

improvements are so let's just go ahead

and take a moment to look at this code

here I'm going to go ahead and get the

drawing board out now on line six what I

have here data let's just go ahead and

draw the array

and it's got four elements with the key

idea being that we're zero indexed and I

can put in some integers here now these

arrays aren't initialized so we don't

know what's actually in these memory

here but in our other example where I've

done initialized and with three elements

I know exactly what those three elements

are because I've used a initializer list

here

so let's just go ahead and label those

here

in each of the indices one two and three

okay so that'll get us started here and

that's our C style race now these are

fixed size here so this will also be an

important note for standard array when

we talked about them again to note that

it's a fixed size

array

otherwise meaning we cannot

resize okay so if it's all these four

elements it's always going to be four

elements if it's three elements with the

initialized data it is three elements

Okay now what's the issue here well when

we use these arrays here we know some

things like what their size are so let's

just go ahead and print out size of data

and let's just go ahead and see what

this results in so go ahead and compile

this I'm going to use C plus plus 20 we

don't need that but again I like using a

latest uh version here and of course uh

let's see looks like I'm getting an uh

error here let me make sure I save

recompile this and

uh fix this little semicolon here sorry

about that let's make sure that we type

out everything properly so you can

actually see the size here

and now go ahead and output this now we

get the size here of 16. and that's

reporting back 16 because I have four

integers and the size of an individual

integer is four bytes now if I have this

array that's stack allocated which is

true here so I'll go ahead and put that

note here stack

allocated

so for example

four byte

integer

times four equals 16 bytes as we've seen

in this example here

but what happens if I try to check the

size of this particular array if I

passed it into a function so let's go

ahead and do this experiment here

and I'll go ahead and just call you know

print array and I pass in uh well what

exactly do I pass in do I pass in uh

data four like this let's go ahead and

give it a try here

I'll go ahead and try to take the size

of data

and let's just go ahead and see what

happens here

so

um it looks like it's going to compile

but it is giving us a warning let's just

go ahead and try it anyways just so we

can reveal what the problem is here so

I'll try to do print array pass in data

and let's go ahead and try to run it

that's giving us some warnings

but let's ignore those warnings and we

can clearly see that the size of data

here is printing out eight now and the

reason for this is that arrays Decay

into pointers when we pass them in a

function even if I'm passing it in here

with the known function size and let's

go ahead and just reveal that in the

warning it says warning size of array

function parameter data will return size

of pointer because we have an array

which again decays to a pointer size so

typically what you have to do with these

types of functions here is you put a

comma and then you say what the actual

size is and then you figure out you know

size of whatever your type is time size

and again that will print out the right

results here so let's go ahead and

modify that and we could go ahead and do

you know size of or rather that we have

four elements in this particular example

and then we can get the right result

so really there's two pieces that we

want to keep track of with our arrays we

want to know what the data type is what

we're storing in integer so let's just

go ahead and Mark that here

as a sort of a property of our array

that it's a what we call

homogeneous

type

meaning

all

elements

are the same

type okay so if they're all integers

they're all integers if they're all some

custom type they're all that same custom

type

and then the second piece of information

that we want to usually have or figure

out is the size of the array so that is

what is our bounds here so is it three

elements four elements Etc okay so now

that we sort of understand arrays C

style Rays what's the point of this

standard array that we have here that

we've included well the very first thing

that you're going to notice is it is

something that's consisting of a type

and a size the two pieces of information

that we actually want to carry along

with us if we're working with an array

so that's kind of cool that we have this

container containing these two pieces of

information that we would want and then

we don't have to deal with this issue of

passing around size here okay and this

issue of an array decaying to a pointer

Okay so

let's go ahead and include array here

and let's go ahead and refactor

how this program will work with our new

array here so I'm going to go ahead and

just comment this out

and let's just go ahead and create an

array with the two pieces of information

that we need so let's bring this in here

just so we can see again the type int

that's the first template parameter on

the size here four okay and I'll just

call this data

and we've got to rework things just a

little bit I'm going to keep the old

functions here just so you can see the

comparison for a little bit

and we'll just go ahead and type this

out again void print array

and this time when we're passing it in

we're going to say the specific type of

array that we're taking in so int for

uh for our data

or let's just call this uh pram here

and then we could go ahead and print out

the well let's figure out what the size

is but now looking at our array and

again because this is a class and it has

the data associated with the

actions or I should say member variables

and member uh

variables we could go ahead and just

query the size here we have the actual

capacity that we need so let's just go

ahead and say Ram dot size okay now of

course we'd be able to figure this out

here uh based off the actual function

that's being passed in but we have that

ability right we don't have to figure

out whether well we're within our scope

or in a function again that size is

carried with the actual uh elements here

or this actual data array here okay so

let's just go ahead and run this just so

we can go ahead and see how it works

here compiles and runs fine so we could

go ahead and see uh the first thing

that's going to print out well the size

is well in this case 16 uh maybe I

printed I picked a bad number we can try

you know five or let's go ahead and

change this around here so that we have

five elements

just to go ahead and show you that uh

what this is showing you the size of um

I just wanted to pick a non-round number

here is in fact figuring out that hey

you've got you know a static array just

the same as the C style array so it's

the same sort of functionality here but

if we actually want to query for a size

we can be explicit about what we're

actually querying for okay now if you

want to go ahead and try this out let's

go ahead and try this same experiment

let's see size of RAM and let's see if

that gives us the right Behavior so now

it is in fact giving us 20 here so we

can avoid running into those types of

Errors meaning that usually when we use

size of we want the exact number of

bytes here okay so again 20 that's the

size of the data here within our print

array when we print off the size we get

the number of elements again just being

explicit about what we're doing there

and when we print out a size of param

here that's being sent here it's not

decaying into a pointer which is always

eight uh bytes on a 64-bit architecture

or I should say you know 99.99 of use

cases that's probably true so again we

could just be very explicit about it

now how is this actually working well

again it's working pretty much the same

way as C so it's a fixed size so that

doesn't change we can't resize it it's

not like a vector which we'll learn

about later it is stack allocated uh

again as it's being placed it on the

stack here there's no new calls or

mallex or anything so we know what the

actual size is and the actual elements

that it has is well in this case if it

has four or five elements however many

the actual elements uh stored here okay

so just works like a regular array now

since we are working with templates that

means we're sort of generating code here

so let's play around with this example

just a little bit so you can see some of

the advantages and different trade-offs

here like what if I change this to 4

here and I have a mismatch here well

I'll go ahead and compile this and well

immediately I'm going to get an error so

let's go ahead and see how the compiler

tries to help us out here

and let's go ahead and just flip the

window here so you can see a little bit

better

and we can see here it's saying could

not convert data from array of whatever

it sizes from five to four here okay so

I figured out what was being passed in

here which is actually quite a nice

message and we need to actually change

this to five so it does have to match

and what's the advantage of this and

what's the disadvantage well the

disadvantage I suppose is we could end

up having a lot of these different

functions with print array for elements

of four five etc etc for the actual size

here now we could probably use some

techniques to uh make our code manage

with that a little bit better or just

make this a templated function that you

know takes in the parameter and then the

size could be deduced from the actual

function call so there's little tricks

that we could do to fix that but that is

one thing that we have to keep in mind

here that for instance uh when I go

ahead and write this code here and what

I can actually do here is do uh let me

make sure I'm using C plus plus 20 here

I can just do Dash e of our main file

and we'll actually see that there is a

specific version of this function uh

that's uh that we're using here again

for five and again if we had to do this

for four so this is the actual

preprocessor output again if you had

lots of different functions you'd get uh

different copies of say this print array

function for each specific use case Okay

so that's sort of a disadvantage anytime

you're using templates you're generating

code if you've been watching this series

or you can go ahead and check the

playlist and look for the uh where I

talk about templates and generics that's

the idea but what's the sort of pro here

and this is sort of a nice

um Advantage here well let's go ahead

and just look at what we're doing here

with an array since this is templated

with the size here

what we can actually do here is for our

actual container again it's equivalent

to a c style array so it's not really

carrying this extra information around

with it on the actual size in fact let's

go ahead and look at the size member

function here so go ahead and click on

it and we can see that this is cons

expert so it's figuring out the size at

compile time so it doesn't appear to

ever be you know querying at runtime so

we're not really paying for that cost so

if I'm going to use other functions and

introduce you to a few other functions

here like at and check for a specific

element here I'm kind of getting that

for free in a way here so let's go ahead

and try this here let's just go ahead

and print out some elements here it's

our data at four

and let's go ahead and I'm going to come

out with a few of these things here just

so you can see the one example

um and let's go ahead and compile this

and actually let's populate this with

some data just so it makes a little bit

more sense uh one two three four five

okay and we could go ahead and see what

our data is

and it prints it out at five here okay

the fourth index okay so that's kind of

nice that that works here and it's

caught a compile time so let's go ahead

and check uh at eighth for instance and

I'll try to compile or should rather say

it's uh it is balance checking here the

actual side so we can actually handle

this exception here if we go uh out of

bounds so that's actually quite nice

and of course we get the subscript uh

operator here so we can actually just

put in something like this now let's put

in a legal value here like zero so I

could just get the first element now

some compilers um and I believe this is

implementation dependent

um if you put it in debug mode it will

also bounce check if you're using the

subscript operator but if you want to

explicitly do that and again try to

handle an exception that is thrown then

you can use the uh dot at operator okay

it's something we haven't talked about

as much let's go ahead and see at versus

uh operator here

uh you'll go ahead and see that they're

very similar in their behavior here okay

so I can just take a look at that here

okay so returns reference uh with bounds

checking uh this one uh just the

operator no bounds checking performed

but again some compilers might uh

depending on if you're compiling with

like debugs uh defined

um actually do some bounce checking or

there's ways to it enable that depending

on your standard Library okay so let's

go ahead and keep talking about arrays

here a few different things that we get

access to and again sort of the pros of

why to use standard array versus again

this sort of C cell array well then we

get all the advantages of things that we

can do with arrays for instance uh using

iterators there's various uh helper

functions here there's a nice one like

fill for instance

um which I think a lot of folks might um

end up using here so let's go ahead and

just comment out our initialization code

here

and something that you might want to do

here is just fill with zeros so let's go

ahead and uh compile this let's run it

you get zero here okay uh and then we

can of course use all of our standard

library and our algorithms that we're

going to learn about later but let's go

ahead and just do something

um simple here let's just go ahead and

create a for Loop for all of our

elements

um and let's just go ahead and print

them out here

Prime data

and I'll go ahead and just copy this

here just so we can see everything else

uh in our array

okay so we should see that it is zero

filled and we get zeros here and again

if you've been following this series

there's other stuff you might want to

consider for example if they're not

going to be modified and if you want to

avoid copies you can uh you know pass

this by reference

so again you can see that you have a

zero filled array okay now let's go

ahead and just look at a few other

things here again just to show you some

of the benefits here uh let's go ahead

and populate this with a few uh

different numbers here and I'm going to

kind of just mix them up a little bit

here and then let's go ahead and we'll

get rid of fill here and let's just go

ahead and call sort

on our data let's go ahead and see we

should get some compiler errors because

we don't have sort here so we're going

to have to include

algorithm here

um oops it looks like we have to include

some arguments here getting a little bit

ahead of myself with the ranges here uh

so again because we get to use iterators

we can do that begin data dot end and

then we can have a third argument if we

want

um for the sort of

um

uh if we want a custom sorting rule here

okay well let's just go ahead and see

how it sorts by default so we get two

four five eight eleven uh that looks

like a sorted array to me so that's

pretty great to hear that we get that

for free okay so we'll get into some of

the algorithms and some things uh later

but just wanted to go ahead and sneak

that in here all right now

um what happens if you know I'm making

the sales pitch here saying that

standard array is probably a better

thing to do in many instances if you've

got a C plus plus code base but if

you're working with some C code you

might also need to interface with that c

code so for that you do have

um

dot uh data here if you just want the

underlying array okay so let's say that

for instance you're working with some

Legacy uh C code base here

and you've got to take in a int star

with some you know element here and the

size sort of the classic uh pattern that

you'll actually see here

so what you can actually do here is

using your uh what I would say is a more

type safe version of an array here let's

call that Legacy the code base let's do

data and I should actually uh let's give

this a little bit of a better name here

how about ARR for array

and let's just go ahead and substitute

these here data for array there we are

and let's do array.data and array dot

size and then we can just pass in those

two uh member functions into this Legacy

C code base function and again it'll

actually pass in the underlying data and

then the underlying size here so you get

that sort of compatibility you're not

really losing anything again in that uh

Way by converting your code or

preferring to use standard array again I

would just prefer this it's safer it's

just as performant again because you're

allocating on the stack again you know

the size just easier tool to use and I

think even with things like using array

you start to find yourself using more of

the algorithms I think it just sort of

encourages more of that Style versus

writing lots of raw for Loops which

you're going to sort of see as a trend

in some of these lessons here all right

so let's just do a quick little overview

again of some of the other functions

here because these are going to keep

reappearing over and over and over again

as we explore the standard template

library but we look at it at the

subscript operator there are some

interesting operations like front and

back and then dot data was the example I

wanted to show you just if you need the

underlying pointer to the array of data

or to interface with c-style code bases

we looked at iterators briefly size we

looked at briefly and then there's a few

other helper functions here like empty

maximum possible number of elements

which I think in this particular case is

just going to be the same as size for

arrays let's actually take a look at

that here now that might vary here ah

this is oh this is giving us the maximum

size due to system limitations here

let's actually run that here just so we

can see explicitly the difference

because I think that'll be useful to see

um for us let's just print it out here

array Max size and again that's actually

a nice thing that we can just query that

uh right away here

uh so let's see here it is okay just

going to query and give us the size of

the container there

um and that's actually what this says

here let's see for standard Ray it's a

fixed size container so it just gives us

the the value here okay

um so that might be a pattern that we

look at uh later on if this shows up

into other uh data structures here again

it's good to just kind of look through

these and see what tools are available

um and then we looked at fill here we

can swap arrays here which is quite nice

and there's even Little Helper functions

like converting things to uh standard

array here so some useful examples there

as well that you might want to play

around with

um as well uh so converting a say

character string

and making sure that or this is sort of

a string literal excuse me here with the

null Terminator again uh would be four

characters all right

so with that said that sort of ends our

tour of standard array I hope that was

useful to see some of these examples uh

standard array again is the first of the

containers that we're looking at so you

can go ahead and see the containers

library and something else that's useful

just in CPP reference if I zoom in on

this is to see the different container

types if we're just thinking about them

on how they're sort of organized

um what we would call uh let's go ahead

and look at it specifically in Array

here is this is a sequence uh or it

satisfies rather the sequence containers

uh satisfies a contiguous container and

uh let's see the reverse bulk container

um in these cases so you can kind of

look at those again if you're newer

learning the different data structures I

think it'd be useful to click on these

and say okay what's the requirement of a

sequence container these will be useful

later on when we talk about things like

iterators here and these are actually

all the rules

um again just something to know about

not something to probably memorize at

this point if you're just learning about

standard array all right folks so that

was our second look at standard array if

you want to backtrack and haven't

checked out already I've put all these

lessons here if you want to track your

progress so you can see the other

previous lesson where we talked about

standard array and C style arrays way

early on in this series feel free to

check that out I'll keep reminding folks

that this is a resource that this that I

encourage you to use if you want to

track your progress and don't want to

explicitly just watch the videos on

YouTube but either way as always thank

you for your support thanks for watching

and I'll look forward to your questions

below please let me know if you have

other use cases for standard array if

you've implemented maybe something

custom on type on top of this or you

know if you are in fact a Advocate as

well as using a standard array and as

always thank you for your time and your

support and I'll look forward to seeing

you in the next lesson

Loading...

Loading video analysis...