Hello again! In this video, we're going to look at the array, string and vector in C++.
We'll start with the array. This is a block of contiguous memory, so this means that you have a block
of memory with elements, all one after the other, with no gaps in between them.
This block is indexed, so there are numbers zero one, two three and so on.
For some reason, computer programmers always start counting things from zero.
So if you say I want the element at index 17, then the program will jump straight to that.
And it's a very fast and efficient
way of accessing memory. And modern hardware is actually optimized to work with this kind of structure.
Arrays came from C, so they're a bit basic.
We can allocate an array on the program stack, so we can have a local variable, which is an array, and gets
destroyed at the end of scope.
But to do that, the array has to have a fixed number of elements, and you have to know in advance how many
elements you're going to have.
So you can create an array which has five elements because the number five is known in advance.
If you want to use a variable, that won't work in standard C++, unless the variable is a constant. And for aconstant,
it has to be initialized.
So the compiler will know what value it has. There is actually an extension in Gnu C++, which does
allow this, which is rather annoying.
Even
if you say you want standard C++, it still does it.
You have to say you're being pedantic to turn it off.
I think the reason for that is you are actually allowed to do that in C.
But the implementation in C is a bit of a hack, which is why C++ hasn't adopted it.
We can also have a dynamic array, which means that the memory is allocated on the heap.
And if we don't know the number of elements in advance, then we have to do that.
Or if we want to be able to vary the number of elements, then we have to use a dynamic array as well.
And to do this, we use the new operator. And then after the type, we put the number of elements in
square brackets.
So this will allocate enough memory to hold that number of ints, and it'll return a pointer to
the start of the allocated memory.
And then we can store this in this address,
pArr.
And then that memory will be allocated for the program until we explicitly release it or if the program
finishes, then usually the program will go and release the memory before the program actually exits.
To release the memory, we need to call delete and we must give the form that uses square brackets. So
there's actually two forms of new and delete, one which doesn't have square brackets and one which does.
And you must not get them mixed up as otherwise bad things will happen.
So this will take the address of the start of the memory block, and it'll release all the memory that
was allocated by the corresponding call to new.
C has a rather rudimentary form of strings.
It's an array of constant char.
Each character in the string is stored as an element in the array, so we have something like this.
So there's the array, the block of contiguous memory.
Then each element in this array has a single character.
And then at the end of that, there's a null character, which has the value zero. Not the character
zero, the actual number value zero.
These are all stored as codes, which represent different characters.
And then if you use C functions to manipulate these, these will look for the terminating null.
So they're rather slow, because they have to look all the way through the string.
And also, if the null isn't there or it gets lost or put in the wrong place, then all sorts of disasters
can happen.
So this is not terribly safe.
When we have a string literal, this is actually a C style string.
So if we have...
(Excuse me)
If we have an expression like this, then the array will be allocated for you.
So that's equivalent to making an array of const char, which has those letters as the elements and it's
null terminated.
So this is all stuff that's inherited from C.
In C++, we have a standard string, this is actually part of the C++ library, not the core language.
So this is a class.
The class has a member, which is a dynamic array, so it has memory, which is allocated on the heap
to store the elements.
And it also has another member which keeps count of how many elements there are in the string.
So it'll look a bit like this.
So we have the string class.
It has a pointer to characters which stores the data.
So that's the block of contiguous memory, and it also has a member, which stores the number of elements.
So you can think of this as being a bit like an array which manages itself.
So it's a kind of object oriented string, as opposed to the procedural string in C.
So objects of this class, the standard string, they behave like a dynamic array, so they allocate
memory on the heap and it gets released.
But we can use them like a local variable.
So if we create a variable, which is a string, the constructor for this will allocate storage on the
heap and it'll populate it with this data.
And then when the program gets to the end of the scope, the destructor for the string will be called.
That will release the memory.
(Should really use shorter sentences!)
The class also has special member functions for handling, copying and assigning objects, so that's the
copy constructor and the assignment operator.
And this will make sure that these are handled correctly by allocating a new block of memory when needed.
And if we change the size of the string, if we decide to change that to "hello, world".
So we need extra storage than the string class will automatically allocate the extra memory and make
sure that the data is correctly populated, so it makes life a lot easier.
We can use these same subscription notation with strings that we use with arrays, so we just put a
[square] bracket with the index of the element
we want. The elements are indexed the same way, starting with zero as usual.
And it also has a size member function which returns the number of elements.
If we could look at a string in memory, we'd see something that might be a bit like this.
So there's the actual string object, so it has this pointer to the data and this member which has the
number of elements.
And then this pointer will be pointing to some address in memory somewhere.
And this memory block will store the actual data for the string.
We also have a standard vector, which is similar to a string, but the difference is that in a string
the elements have to be characters.
In a vector, it can be any type you want.
So we could, for example, create a vector of ints and do that.
We put "int" in angle brackets after the word vector, and that's known as a type parameter.
So in this, we're creating a vector of ints, and we're using this list initialization that we saw before.
So we're creating a vector of ints with the values four two three five one.
So it's a similar structure to the string. We have a member which is a dynamic array but it's going to be
a type which is the same as the parameter.
So in this case, we're going to have a block if ints, so this is going to be pointer to int. And and we have
the size member again.
And similarly, we can use subscript notation to get data using an index so we can get an element's data.
There's a size member function which returns the number of elements and there's a push back in the function,
which will add a new element at the back of the vector.
So if we have our vector with these elements, then we call push_back.
The class will add the element six at the back of the vector. If it needs more memory, it will allocate it.
And the vector in memory looks very similar to the string.
And here we can see we're doing a push_back operation, so the element six is being added at the back of
the vector.
OK, so that's it for this video.
I'll see you next time, but meanwhile, keep coding!