Placeholder Image

Subtitles section Play video

  • hello and welcome to something a little bit different from a I'm going to be talking about a specific feature of the C plus plus language pointers on.

  • I felt there was a need to do this video because UN discord and on YouTube and very male, I've been asked quite a number of questions about people's code that doesn't work on dhe.

  • Invariably, the problem seems to lie with a misunderstanding of how to use pointers in the first place.

  • So this is a little video I can use to excuse the pun point people in the right direction if they do have any problems with pointers in my video output to date, I've never really targeted a specific audience, and I'm trying not to with this video, either.

  • So it doesn't really matter if you're a beginner or intermediate.

  • Maybe there'll be something in this video that will be novel to you, and even for the non c++ program is out there that still really recommend watching it.

  • Because point is a fundamental regardless of which language you're using.

  • It just could be that other languages are hiding the fact that pointers are being used, So let's get started by asking the question.

  • What are pointers?

  • Unfortunately, there is a very, very simple answer to this question.

  • A pointer is just a variable that holds a memory address.

  • I repeat, a pointer is just a variable that holds a memory address.

  • If you like this video, give me that.

  • No, I'm only kidding.

  • There's actually a lot more to it, but fundamentally, it is really that simple.

  • I'll start by just introducing the basic syntax, but fundamentally, it's important to know that whenever woodworking with pointers were working with memory, and so here I've drawn some random access memory.

  • Some ram on I've got a column, which represents the addresses.

  • So this is the location in RAM on a column.

  • Represents the value at that specific location, have not populated any values just yet.

  • So let's assume in our program we have something along the lines of int A equals five.

  • We've asked the compiler to make sure that our program will have enough memory to store variable called a and give it the value.

  • Five.

  • Now we know that variables of different types of different sizes will not worry about that too much here, and so just to calm down the masses.

  • Let's assume that all the values are 32 bit when we write something like this in our program, we don't really have any control over where it goes in memory.

  • And we don't care either, because what we care about is that we can represent that location in memory through this variable name A.

  • Let's say the compiler has gone unused.

  • Memory address location 102 which will stay, is a and it's given it the value.

  • Five so loosely in our program, wherever we see the variable name, eh?

  • What we really mean is go to somewhere in Ram and look up address 102 which corresponds to a and return the value five.

  • So, to all intents and purposes, the variable name disappears on.

  • This situation is known as direct.

  • Addressing where we take a symbol on it directly corresponds to a location in the Ram.

  • Now, as discussed, a pointer is just a variable that holds a memory address.

  • So in our simple system here, let's create a variable type pointer on.

  • We'll call it be just a zit did with the interview.

  • The compiler will go on somehow structure our memory so that be stored somewhere in it.

  • So let's say here, be it started address 104 We've had no control over that.

  • It is where it is, but the value be holds is going to be a memory address so we could declare it explicitly.

  • B equals 100 for example.

  • So the value goes to 100.

  • What I'm trying to demonstrate here is there's absolutely no difference between the two things.

  • A pointer is just a variable that holds an address in memory.

  • It's very rare that will actually set the value of a pointer explicitly and numerically like this.

  • Instead, it's more useful to use the location of an existing variable in the program as the value that we give to the pointer on DSI in C++ provide something which is the ampersand symbol which behaves like get the address off a variable.

  • So here we've said our pointer be We want to set its value to be the address of wherever a stored.

  • So in this case we can see a store that address 102 So the value stored in point B is one oath two.

  • Now that we have a location in memory that stores a value, which represents a memory address to a different location.

  • We've implemented something called indirect addressing.

  • And so whereas we had an operator that allows us to get the address of a variable, we can have an operator that allows us to get the value at that address.

  • So let's create 1/3 variable into sea.

  • But I want to get the value from the location pointed to buy B and in seeing c++, that's the ass tricks operator confusingly not multiply in this case.

  • But this means get to the value at, so we want to get the value.

  • That's the location pointed to buy be.

  • So how will this be interpreted?

  • Well, the compiler will have created the symbol.

  • See, somewhere in our memory, for what we're saying is, please get the value at the pointed to location of our point of B.

  • So we'll look at the value of B, which is 102 in this instance, and we'll use the value of B as an address off the actual value we're interested in.

  • So this 102 points to a effectively, which is what we've set up here on, we'll get the value.

  • Five.

  • We have indirectly set the value of C to a using a pointer, be and that really is all there is to pointers, as I've stated, and I will state many times in this video that just a variable that holds a memory address.

  • But even in this simple example, we've started to see some confusing syntax we've introduced to new symbols now the address off symbol for enough.

  • But we've started to use the multiply ass tricks to represent Get the value off, and I think it's this usage of additional symbols that makes point is quite confusing to those that haven't seen them before.

  • And in fact it gets even more confusing because there is no variable type called Pointer.

  • As we'll see in the following practical examples, it's important that the compiler on the program and know what type of information the pointer is pointing to.

  • So we have to include the type somewhere in our point of definition.

  • But clearly we need to include something else because this is now saying that be is just a type interject, no difference A and C well in c n C plus plus to say that this is a pointer to an interview.

  • We include the ass trick simple again So we can read.

  • This is saying, Please create a variable that holds a memory address to another variable that is an interview on.

  • Sometimes you'll see it written out like this, and sometimes you'll see it written out like this, both of valid But Tut, tut, tut C and C plus plus were using the same symbol again to represent something else.

  • So now it represents.

  • Please declare Mia's a pointer and hear it represents.

  • Please get the value pointed to buy this pointer on.

  • When it's not in the context of pointers, it means multiply.

  • Fortunately, as long as you get into the habit of thinking methodically about how Pointers Air constructed, he won't get yourself into too much trouble.

  • It's quite important that Pointers know what type of data they're pointing to, and this is why.

  • So let's assume we're now working with one bite per location in our memory address.

  • So eight bits we know that in a C and C plus plus program, more or less all the time and in it is going to be a 32 bit value, so I compile will go on, allocate some memory for Variable A, but it'll take up four locations.

  • So let's assume that sticks it here at Location 100 our 32 bit variable will take up four locations in Ram.

  • That's just to know Jesus a zero a one a two on a three If I create a pointer again, so int star b equals the address off a on this time, let's assume that Bay has been created somewhere else in memory.

  • It's given the value of 100.

  • If I were to increment the pointer, so B equals B plus one.

  • Giving me the value 101 is not that useful, because now I'm 1/4 of the way through an ent.

  • What is typically more useful to the programmer is to move in a hole into step, so incriminating the pointer by one like this is really the same as saying.

  • B equals B plus the size off in fights often incident, which is the same as saying B equals B plus four on our system.

  • So our original be value pointed to the memory that represents this interview if we increment it once, we then start to look at the memory that represents the next interview, and this is quite useful.

  • But before we get ahead of ourselves, let's look at some practical examples I've created here, an absolute bird bones program to help explain the basics of pointers.

  • I'm going to introduce pointers by first talking about a raise.

  • So here I've created an array of 10 introduce called Some Array.

  • I'm not even bothering to initialize it, and the reason I've chosen to use an array is that in this situation, the compiler will create an array which is contiguous, and this means that the memory that will be used for this array will be complete and whole will be no gaps in it.

  • Nor will there be any obstructions.

  • There'll be a single solid block of memory allocated to implementing this array.

  • In this case, it's 10 inter jizz on.

  • We know that inter jizz of four bites, so we would expect 40 bites of memory uninterrupted to represent this array.

  • Here I've created two pointers.

  • We can see the interview on the ass trick symbol indicating that I'm creating a pointer of type interview I call this one location six on Dhe.

  • I'm going to point this pointer at Element six of the array that we've created.

  • So standard array notation here grabbing the six location in the array on.

  • I want the address of it.

  • So there's the address off operate on.

  • I've done exactly the same.

  • Another pointer, this time going to Location zero, which is the start of the array.

  • I'm not going to do something little strange.

  • I'm going to display the value of the two pointers on also the difference between them.

  • Let's take a look.

  • Well, here we've got two numbers on the difference between them is 24.

  • Location six is 24 larger than location zero, but the difference is just six.

  • Will this make sense if we've got six positions in contiguous memory apart from each other on each one of those positions represents a four bite thing in this case, an interview.

  • Then we've got 24 bites difference between the two locations, and this is exactly what we saw is the difference between the two numbers.

  • But when we subtract location zero from Location six as pointers, it returned.

  • The difference in this case in whole Inter Jizz, which were six, which is fair enough.

  • Well done it again.

  • This time we'll see the numbers are different, but they still differ by 24.

  • And the only reason I'm showing this is to emphasize that you don't really have that much control over where things go in memory when it one last time again.

  • Different numbers on the differences 24.

  • So the fundamental distinction to make here is that the memory addresses work on a per bite basis.

  • But the point is themselves well, they work in a space defined by the type of object that they're pointing to.

  • In this case, an interview.

  • We see that we declare a pointer by including the ass tricks at the start, and we've used the address off operator to get the address off something.

  • In this case, it happens to be Location six in this array.

  • Now, I noticed some of you that may have gone well over your head, but persevere because I'm going to show some other examples.

  • I'm also going to show situations that can catch out the unwary programmer.

  • And I hope by the end of this video it will all sort of gel together and you'll start to get the bigger picture.

  • I'm not going to give our race, um, values like giving it 10 values, which is just multiples of three.

  • And I want to demonstrate different ways of accessing the same data.

  • I'll get rid of this here.

  • We're using the address off operator off a location in the array.

  • In this case, it's the zeroth location.

  • We want the very beginning of the array.

  • Well, a raise don't have any pre cursory information attached to them.

  • So the zeroth Elements is really the start off the memory that was allocated for that array, which means, in fact, don't even need to do this.

  • We can simply say that's our location.

  • P Location zero equals some array because some array is, in fact, a pointer in disguise and you see no red lines.

  • The compiler is quite happy to accept this over.

  • I'll just put that back for clarity.

  • Let's display the contents of the array just to prove that it works.

  • But let's look at different ways of doing the same thing.

  • Now we know a thing or two about pointers.

  • We know that some array is just a pointer.

  • It's P location zero.

  • So the shit out put a memory address 10 times.

  • Since we know some array is the same as the zeroth location of the array.

  • We can use pointer arithmetic to add an offset to it.

  • So in this case, I'm going to add the I value.

  • So we'll take the zeroth location of our Ray, pointed to buy some array, and we'll add 01234 to it.

  • Let's take a look.

  • Well, we can look at the numbers this time when we see that they differ by four each time, conveniently the size of an interview.

  • So if that's our memory address, we should also display the value.

  • So I'm going to put in just some friendly text.

  • But this time we want to get the value at that location.

  • So summer?

  • A precisely.

  • But if you remember, the value off operator is the ass tricks.

  • Let's take a look, and this time we can see it is now displaying the contents of memory at that location, Yet we've not indexed it like an array at all.

  • Don't forget.

  • A pointer is just a variable that holds a memory location.

  • So here is that variable on.

  • We're increment ing that variable on displaying the memory location, but we're using the value off operator to return the value stored at that memory location.

  • We can do similar things in a slightly different way.

  • We know P location is the start of our array, so let's output that value and we'll also output the data stored at that location as we've just done so here.

  • We've got the address on here.

  • We're using the value of operator to return the value, but this time I'm going to increment are pointer each.

  • It's aeration of the loop.

  • Let's take a look.

  • And, as expected, we see the memory address is on the values at that memory address.

  • I'm just trying to demonstrate the flexibility you have with pointers on point arithmetic.

  • Let's just briefly examine why pointers may have a reputation for being more complicated than they are.

  • Let's consider the same example is we've just seen.

  • But this time, instead of it being an integer, I'm going to use a type char instead of an interview, right?

  • It's ah, well, it's an array of chance.

  • It's a string.

  • Hello, Well, then the type change we can see.

  • Everything is just the same on as we did in the very first example.

  • I'm taking two pointers to two locations and I'm going to display them.

  • Let's take a look.

  • So we're printing out what this string is.

  • We've got to memory addresses in this case, the only three apart, and it says the difference is three.

  • And that's because a single char is a single bite.

  • That makes sense.

  • But let's see what happens when we take these casts out off the location values.

  • Well, we start to see something a bit weird.

  • We see the two strings, but we see fragments off them.

  • In fact, location three starts from the third element of the string on location zero clearly starts from the beginning of the string on.

  • This is very confusing.

  • Let's say we didn't actually initialize it as a string.

  • We just initialized 10 bites of charm and now we run it.

  • You know, things are just getting worse here.

  • What's going on?

  • And that's because when you see Charles on pointers of Charles, it's very common that you're actually inferring a string, and so there's quite a lot of operators, amongst many functions across C and C plus plus that expect to see pointers of type char representing strings.

  • And so they do string specific things.

  • So in this case, this char star location three is being treated just like a regular string.

  • That's why we're not seeing the value of the address here unless we explicitly cast it to an integer.

  • So just a little bit of a trap for new place.

  • Some functions are expecting.

  • Pointers on will behave differently, depending on the types of pointers they receive.

  • Right now, for something a bit different, I'm going to create an object.

  • Some object.

  • The object has two fields x and Y on.

  • I've declared that X and Y be initialized with these values.

  • A three a two, a one, a zero in hex.

  • I don't really care what the numeric value is here.

  • I'm more concerned about the hex symbols being used because we're going to use the de booger toe.

  • Look at how this object has moved around in memory.

  • If we wanted to create one of these objects in our program, the easiest ways to simply declare it, and if we wanted to create an array of them.

  • Well, we'd stick of value at the end.

  • This is really basic stuff, and when we do this, we have actually created this memory on what's called the stack.

  • It's known that compile time what is required here so the compiler can go and deal with it all for you.

  • Let's just take a quick look at that running, but I'm going to use the de booger, so I've run to the line on what I can see.

  • I may try and zoom these windows so they're a bit more clear for you.

  • But when we create the object some objects we can see that the points of value has become populated on.

  • We can take the pointer object and drag it onto a memory window and actually have a look at the memory.

  • And so we can see here that are simple.

  • Structure of two types of vintages is a zero a one a two a three B zero b one, b two b three, and we'll see that repeated 10 times.

  • It's exactly what we needed.

  • I got a little curious at this point and decided to ride in a constructor because I wanted to test.

  • Was the compiler actually going to call the constructor of the object?

  • Take a look, so I run the code.

  • Grab my point, sir.

  • Bring it over to the memory window and we could see yes, it does.

  • In fact, whilst it's allocating all of those objects for that array, it's calling the constructor because now we cc zero c one c two instead of AIDS and bees.

  • Now, this is great if we know in advance how many of the objects we're going to need.

  • But what if we don't?

  • Well, instead of using the stack, allocation will allocate on the heap instead, we'll need a pointer to do this here.

  • As we've seen throughout the video so far, we've created a pointer, and this point is going to point to the zeroth element of our ray of 10 some objects.

  • That's because the new key word will return a pointer.

  • We don't know where the OS is going to put this array, but we need to know where the staff of the array is.

  • So it makes sense that we have a pointer that represents that location in memory because the point is just a variable that holds an address in memory.

  • And so this is quite a useful technique for run time allocation of memory.

  • But let's take a look how these objects get constructed.

  • We're in the deep again.

  • Concede right now on my Pointer has no specific value.

  • If I drag it over to the memory window, it's it's undefined.

  • We can see the De Booger has returned a pointer and given us the memory address value and that the data pointed to at that address is what we expected to bay.

  • So far, so good.

  • Nothing is any different.

  • However, Whenever we request memory from the operating system at Runtime, it's really, really, really, really good practice to give it back.

  • So we have to clean up after ourselves.

  • But fortunately we know where the object starts in memory and we can call the delete operator because we have a pointer that points to the start.

  • Now let's get all meta.

  • Let's make things really complicated.

  • What if I wanted an array allocated at runtime and it was an array off pointers rather than array of objects?

  • We want to get a pointer to the start off an array of pointers on we're going to create using the new key word.

  • Just stop pointed objects, so these are 10 memory Address is being created now rather than 10 objects.

  • So let's take a look at how this gets constructed.

  • Let's run it and we'll drag the pointer over to the memory window and we see CD CD CD.

  • Oh dear right, It's not quite done It, in fact, what is done is allocated enough memory for 10 points is, of course, it's not constructed the objects we need to do that individually.

  • C.

  • D is one of the cryptic values used by the visual studio D Bugger to say, Hey, I've not been allocated yet.

  • Instead of CD, we can force it to use a value zero in this case.

  • Now I prefer this notation to say Please initialize my memory all two zeros So this time fight drastically object over to the memory window.

  • We can see its initialized.

  • It all two zeros as requested.

  • There is an alternative to this notation, which is to use an open and close parenthesis.

  • I don't like this as much because it looks like it should be a function call.

  • That's why I prefer the explicit curly braces.

  • So now I have appointed to an array of pointers for each element off that array.

  • I want to create a new object.

  • Let's take a look drug over.

  • The pointed to the memory window we can see are zeros so that 1st 1 gets allocated.

  • 2nd 1 gets allocated.

  • 3rd 1 gets allocated.

  • But these aren't C's and D's that you were looking at before or reason.

  • Bees.

  • These are, in fact, memory addresses in their own right, because don't forget peace.

  • Some object is a pointer that points to an array off pointers on pointers are we all know this now all sing along pointers or just a variable that holds a memory address.

  • In situations like this, the cleanup also becomes more complicated to Andi.

  • I'm going to sort of emphasize it's important to clean up after yourself so it once you've done some stuff, you then need to individually a raise.

  • All of those objects, the overall array delete This one will only delete the array of pointers, but the objects themselves still need to be deleted individually.

  • There we go, much better.

  • Now you may be asking yourself why on earth would I need to do something completely as bonkers as of this on?

  • Well, one of several Valley dances is polymorphism.

  • Now, if you haven't got a clue what that means, that could well be the topic of another video.

  • Or at least go and have a look at my code it yourself role playing game.

  • Siri's.

  • We used polymorphism a lot to implement that game, and if you haven't got a ce faras polymorphism in your programming, Journey's just yet.

  • Don't worry about it.

  • You might pick up a thing or two in this very simple example.

  • Really, really briefly.

  • Polymorphism is the ability for one object to behave and look like another.

  • So I've created a very simple object here called some base object.

  • And it's got one method which returns a string that identifies what the object is going to create.

  • An additional two objects that inherit from this base object and they override the same method.

  • So sub object A will identify itself as sub object.

  • A and I had a very similar sub object be so a base class based object and to sub classes of that class called sub object and subject B in Stan.

  • She ating any of these objects is very simple.

  • There's the base.

  • Objects will create a variable called ob base.

  • Likewise, for the two subjects on here I call identify yourself on all three objects.

  • Let's take a look perfect.

  • Each object has identified itself.

  • Let's suppose I want an array off objects on.

  • I want to reiterate through that array one by one and get them to identify themselves well.

  • I can create an array of 10 based objects and create a loop the loops through all 10 and calls the identify yourself function.

  • And if I quickly run that well, see, we get 10 based objects.

  • Very good.

  • But how do I set one of the objects to be one of the subjects of Let's pick Object three here and I want to force that one to be object.

  • A No object day is a subclass off the base objects that that's legitimate.

  • That's why the compiler is not complaining.

  • But the wrong identify yourself method is called My Belt a fixed that by adding in a virtual keyword, which tells the compiler that if I am sub classed on, any of my Children happen to override this method, please call the child's method instead.

  • Let's take a look and it doesn't work.

  • And that's because our objects, crucially, are some base object.

  • It doesn't matter whether it's a child, object or not, the array only consists off some base object.

  • What we want really is a structure that allows us to have a mixture of base subjects, object A's and object bees all in the same array on Let the compiler intelligently work it all out as to which method should be called on which object.

  • Let's get rid of this and bring in our pointer to an array of pointers.

  • In this case is an array of pointers that represent our base object.

  • I'm only doing five of them, and as before, I'll get all five of them to identify themselves now were using pointers now instead off actual objects.

  • So we need to change from the period symbol to this arrow symbol.

  • And just before we get slammed for really bad practice, I'll also clean up after myself somewhere to look through all five and delete the individual objects and then delete the overall array off pointers.

  • So after I've allocated my ray, I don't need to create each of the objects individually.

  • I need to do this five times 1234 on.

  • We'll have a mixture so we'll say that one's going to be that one is going to be, well, keep that one as a the end and we'll have base object as well.

  • So now I've got three different types of object being created in a single array.

  • All of these objects implements and identify yourself function, which means that these super objects can have any kind of crazy implementation additional functionality that they want.

  • As long as they provide an identify yourself function, it will be okay.

  • So let's run this.

  • And here we can see our array only consists of one type of object, the base object.

  • Yet individually those objects are unique, and this is a really powerful tool in object oriented programming.

  • What we have avoided is the need to manually try and work out what each type of object is.

  • Faith, for example, having a big if statement or a switch block or something similar through the use of pointers, the compiler on executing subsystem is capable of just sorting it all out for us perfect.

  • Now I'm getting a bit long in the tooth, and I'm a word that arrays aren't very popular.

  • The moment of people prefer to use vectors instead.

  • But exactly the same thing applies.

  • We just add to the new elements to the back of the vector for the identify yourself Function will use an auto for loop, and we'll also do something similar for the cleanup code.

  • But it's important to remember that when you're deleting a vector, all you're doing is deleting the outside container.

  • You're not freeing up the memory internally, so I do want to go through all of the elements of the vector individually and delete them.

  • What's interesting about this loop is the introduction of the address off operator here on.

  • In this instance, it's referring to pass by reference.

  • Normally, when you would iterated through a loop without this operator, A would contain a copy of whatever is in that factor.

  • We don't want that we want to the actual thing that is there.

  • We want a pointer to the location in the vector, so we want the address off.

  • So any changes we make it to the actual data in the location where we expected to be on, not a copy off it on.

  • Once we've deleted all of the elements individually will clear the vector.

  • Let's just have a quick look through the de booger at this and see what happens.

  • I've got the vector here.

  • The size is set to five.

  • It's got five things in it.

  • On each one of those things is a pointer to an object.

  • I'll expand them there, and as we go through each inspiration, we can see that the pointers are being invalidated each time.

  • But what we haven't done is change the size of the vector.

  • Even though we have deleted the elements, the size is still the same, so the vector contains nothing.

  • Now all of our memory has been cleaned up, but the vector itself still exists, so we'll call the Clear Function to get rid of all of the structure that represents the vector.

  • So you might be thinking, Why is he banging on about vectors?

  • Well, let's just simplify the situation completely.

  • Have a vector with just a knob checked in No pointers.

  • It all put the object in.

  • I put a bunch in, but I'm not creating pointers or anything of the sort.

  • One of the most common problems I've identified with people's code is that they are doing something they shouldn't be doing on.

  • That is creating pointers to elements off the vector, and this is completely legal to do.

  • So you can see here.

  • I'm creating a standard pointer to base object pointed to have active element on.

  • I'm taking the address off a particular location in the vector, and this is really, really, really, really, really, really bad.

  • Please don't do this, guys.

  • It's not very often in a video.

  • I say you should or you should not do this.

  • But this is one of these things you should not do.

  • Never do this.

  • This is bad.

  • And I think the confusion starts because a lot of newer programmers treat vectors just like they're a raise.

  • And they're not here.

  • I have some RAM starting at zero, going off to whatever 16 gigabytes.

  • Aram consists stuff from lots of different programs, so this area might be used up by the operating system on this area may be used up by some of the programs that are running.

  • There might be nothing in this area And then we've got another area here with something else.

  • Some other program discord.

  • Why not?

  • And then I got to make it here.

  • We've got chrome using up.

  • Well, whatever is left.

  • When we asked the compiler to create an array for us, say into a 10 what we're saying is, please go and find a block of memory for us that's contiguous and return this starting address off that location.

  • So, for example, it finds maybe the first available block of memory that it can, which is here.

  • So if that is, for example, location 80 it goes to 120 assuming we're working in bites.

  • 40 bites, tenant urges.

  • If we requested Ah, whole bunch of introduced, say, many thousands that couldn't actually fit anywhere in RAM, it would fail.

  • You get you get an exception.

  • Factors are quite deceptive because they look like a raise so I could have a vector, that store's ends and the first time we pushed something back to the vector, it stores it in Ram.

  • That's very easy, and we know that we can access that as be zero.

  • That's a bit too similar to an array for my liking fine as we add things to the vector.

  • We had more and more things to the Ram, and we can keep accessing them because it we're assuming the vector is contiguous.

  • So we get up to a point I don't know, ate whatever.

  • It's fine, but now we've run out of space.

  • If we try to push back into the vector another interview, it can't do it.

  • But it has to remain contiguous.

  • That's what a vector should do.

  • So what happens is the vector become sensitive to this and says, Well, I'll just relocate my entire contents to somewhere where I can be contiguous.

  • It's on the ninth, it oration.

  • It will take all of the contents here, find some space for it.

  • Maybe it puts it here.

  • Copies.

  • It's all over and adds the additional new element.

  • And this is why it is bad to have a pointer to the element off Vector because the Pointer originally pointed to the eighth element here, and that's stored whatever address was necessary to represent that element.

  • But all of the contents of that vector have now moved, but our pointer still points to this original location.

  • It doesn't point to the data.

  • It thinks it's pointing at any more simply because our vector has grown.

  • What's even worse is it's very possible that the data in this original location has remained untouched and still looks valid.

  • So actually identifying that something has gone wrong could be a very tricky book to trace down.

  • In short, never create a pointer to the element of the vector.

  • You can do it, it is legal.

  • And if you are in full control of everything that's going on in your program, for example, you may only be creating the vector once at the start of your program and never touching it again.

  • Then you know you can think about it.

  • But on the whole, I would suggest don't.

  • So far, we've looked at the very basics of pointers.

  • We've looked at pointers and arrays.

  • We've looked at getting the addresses and the values of certain locations in memory.

  • We've looked at doing pointer arithmetic on.

  • We've looked at the roll pointers play in polymorphism.

  • We've also seen some things you should be wary off when using pointers on that.

  • Whenever we create memory dynamically using a pointer, we need to be responsible for cleaning it up, or else the system will simply run out of memory.

  • Unlike other programming languages, see in C++ does not have what's called a garbage collector something looking for objects that no longer have an owner on.

  • More recent versions of the C++ standard have provided mechanisms to help address this, and these are somewhat confusingly called smart pointers on I'm only going to briefly talk about smart pointers here.

  • Smart pointers have been introduced to imply the concept of ownership off memory that is allocated, and there are two fundamental types that you'll see most often in C++.

  • Code on the 1st 1 is the shared smart pointer, which allows multiple things to access the data that is pointed to personally.

  • I'm unsure about smart pointers.

  • They do have their uses on.

  • They can be quite convenient, but I don't like anything that encourages the program and not to think about what they're doing.

  • I like the fact that when using point is, you have to be responsible for allocating Andi allocating your own memory.

  • It makes you think about the journey the data takes through your program.

  • Smart pointers alleviate that.

  • Need to think about it it's still do need to be cautious using a smart pointed.

  • But the idea is when everything is done using a particular piece of memory, it will delete itself, and it just doesn't sit right with me.

  • The idea of encouraging the programmer not to have to think about things.

  • As you can see, I've bought in the structure that we used towards the start of this video.

  • Some object.

  • I'm going to create a shirt pointer and it's quite wordy.

  • She had points it and it's a template, so we need to give it the object on.

  • We'll call it S p.

  • Some object one on.

  • We need to use the command make shared, which is effectively similar to our new command.

  • And again, it's a template.

  • So some objects on we don't have anything to pass into the constructor of the object, right?

  • So that is the equivalent smart point to equivalent to just doing new on a pointer.

  • Fine.

  • And if you're being really modern about it, you wouldn't have the using name space STD at the top of the program on it would be twice as long.

  • What I'm going to do is fake some scope in the program by using some curly brackets, and we're going to have a look at the behavior of a shared pointer as it goes in and out of scope, so we'll create a knob.

  • Jek tw within the bounds of scope one here on will create a second pointer that points to that object in scope to Let's use the D bugger to see what happens.

  • So the object has been created and we can see here.

  • Sp some object.

  • One has some data that looks like our objects associated with it.

  • Trouble is, with a smart point is they don't look as simple as regular pointers.

  • So I grabbed the pointer on Drop it in the memory window.

  • We can see our C zero c one c to d zero d one d to etcetera.

  • Perfect.

  • If we look at the control block off the smart point, we can see another variable uses that tells us it's been used.

  • Once we've now entered scope to, we're going to create a second pointer that points to the same location, the same object.

  • Nothing new has been created in memory, but the number of uses has doubled.

  • The smart 0.2 is now were the two things are pointing to this location in memory.

  • As we leave scope to, we can see the uses has decreased.

  • It's gone out of scope.

  • This object has been removed from the stack, and as it's been removed, its district has been called on.

  • That has decreased the count.

  • The same thing now will happen as we go out of scope.

  • One he uses will go to zero on.

  • When that happens, the memory that is pointed to buy this smart pointer is deleted, and we can see here in the memory window.

  • It's all been set to all dese, which is a D book visual studio, speak for deleted memory.

  • So as a programmer, I've not really had to think about deleting and cleaning up my own memory.

  • It does it for me as things go in and out of scope.

  • There's a second type of smart pointer called the unique pointer, and this means only one thing can have access to the object.

  • And in fact, it's so smart that it won't even let you compile things that invalidate the rules.

  • It has to follow.

  • So here I've created a unique pointer to our object instead of make sure does it was before has now make unique.

  • And as I did before we go into a second level of scope.

  • I try to point a second unique pointer at the same object on the comm Pilot doesn't like it, that's all.

  • It's not that you get the most sensible of error messages, but you can tell something is wrong.

  • It's not going to force me to think about well, hang on.

  • Ownership has to be transferred here.

  • Only one thing can point to the object.

  • In this case, you would use the move Command, which stops it being owned by one unique pointer and transfers.

  • The ownership to the 2nd 1 will have a look again with the de Booger and see what happens.

  • Have executed the first line which has created the object and created a unique pointer to that object.

  • Drag over to the memory window and we can see the object certainly does exist.

  • There will now execute the next line which will transfer the ownership of the object from the first unique pointer to the second unique pointer on.

  • We can see that the memory has remained unchanged nothing has become deleted, but U P some object one is now set to empty.

  • It doesn't point to anything.

  • Where is U P?

  • Some object to now points to the original object as we go out of scope for the second time, there is no further transfer.

  • So at this point, the data should be deleted on.

  • We can see indeed it has because only one thing is allowed to own that's object when it is created uniquely and so there you have it.

  • I think I've covered all of the most basic uses of pointers in C++ and we've even had a quick look at smart pointers that there is no code for you to look at on the get hope this time.

  • But if you found this video useful, please give me a big thumbs up.

  • Could we have a chat on the discord?

  • Have a think about subscribing and I'll see you next time.

  • Take care.

hello and welcome to something a little bit different from a I'm going to be talking about a specific feature of the C plus plus language pointers on.

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it