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 video analysis...