The course is part of this learning path
In this course, we will explore the basic concepts and fundamentals of pointers in C++ and you'll learn how to use them to point to dynamically allocated memory.
- Learn the fundamentals of pointers
- Learn how to allocate memory dynamically and also how to return it
- Explore rectangle and circle classes and create instances of them dynamically
- Beginner coders, new to C++
- Developers looking to upskill by adding C++ to their CV
- College students and anyone studying C++
To get the most out of this course, you should have a basic understanding of the fundamentals of C++.
In the last lecture, we learned a lot about the fundamental concepts and syntax involving pointers. We learned that pointers are variables that can hold memory addresses. In this lecture, we will begin our discussion of one of the powerful features of using pointers, that is dynamic memory. So, what is dynamic memory?
Dynamically allocated memory or just dynamic memory for short is memory that's allocated during runtime instead of being set at compile time. In some situations, you might know exactly what variables you need, how many you need and how you're going to use them. All of the applications we've written in this course are examples, at least as far as we know. But what happens in situations where you may not know how many variables you need or how much memory you need to allocate? In these cases, we need dynamic memory which is impossible to achieve without pointers. You use the C++ keyword 'new', which is the new operator to reserve memory on a special area of memory called the free store, or more commonly referred to as the heap. Let's write some code. So, we're going to create a new project and we will call it dynamic fun, DynamicFun. There we go. And we'll create our main file here, main.cpp. And some of the syntax will be new, literally. That joke will make sense in just a minute. Let's get to writing some code and then we'll talk about. All right, so #include iostream using namespace std; All right, return 0. Excellent. Okay, now int myIntPtr = new int(123); and we're going to print out the reference myIntPtr. Already and delete myIntPtr yep, pointer equals the null pointer and return zero.
Okay, so this was mentioned in a slide earlier and we'll talk about that in just a minute. But it was in the slides that you could get a heads up. All right, so let's run this just to see what it does, see if we get what we expect and we do, we get 123 and that's exactly what we expected. So, nothing too weird was output. But how does the code work? I'm glad you asked. That's why I'm here. Notice that I declared the variable myIntPtr just like I declared pointers in the last lecture. The difference this time is with the initialization. Instead of initializing it to the address of an integer, we declared elsewhere. In main for example, we dynamically allocate memory for an integer and using the parentheses next to the we initialize it to the value 123. We could leave the parentheses off entirely and initialize the actual data value using dereferencing. Let's do that real quick to see what it would look like. So, we could just put new int and then I could just put the reference myIntPtr = 123. That's another way to set the value because remember you have to dereference when you actually change the value of the thing you're pointing to. All right, good. Let's run it again just to make sure it does the same thing, and it does 123. The new keyword or new operator is an operator just like plus, minus, divide. It's just not for arithmetic, it's a unary operator that means it takes only one operand. Of course, the data type or constructor of the type that you're trying to allocate memory for. So in our example, we allocate memory for a single integer. It returns the memory address of the allocated memory. Again, this is a match made in heaven.
Since pointers hold memory addresses, they are perfectly suited to hold the return value of the new operator. Now, we print out the data using the reference operator, just like we did in the last lecture. So, this isn't all that new. But why do we need to use the delete operator at the end? And why do we set the variable to null pointer? Well, here's the situation. When you declare regular variables like integers, double, strings, and even your objects in C++. If you're not using the new keyword, then the memory is allocated on an area called the runtime stack. We discussed the stack earlier in the course when we talked about functions, the memory is managed by the system so that when it goes out of scope it is returned to the available memory automatically.
However, when we define pointers and then used the new keyword to allocate memory for them to point to that memory that's allocated must be returned to the heap manually. In other words in C++, using this type of pointer, raw pointer you have to decide when to return the memory yourself. We call that managing the memory yourself or manually. We do this with the delete keyword. So, in the code when we call delete on myInt pointer, the memory that was allocated is returned to memory. If you don't delete the memory and then assign the pointer to something else, you have this memory allocated on the heap that cannot be accessed. This is called a memory leak. If you have a lot of these leaks in your program will start consuming a lot of memory that it isn't using. So, what's the deal with the null pointer?
Technically speaking, since it's the end of the main function, this isn't completely necessary but it is a good habit to get into. Even though we call delete on myIntPtr and the memory that was reserved for our integer has been returned, myIntPtr still holds a memory address but the address is no longer valid. To make sure it contains a predictable, expected value unless and until it's used again, we set it to the special value null pointer. The nullptr keyword, null pointer keyword represents the memory address at location zero. That's right, zero. And all the programs you ever right, there is a bite that has been sacrificed for the greater good called null. Before C++ 11, null pointer keyword didn't exist. So, people directly set their pointers to the actual integer zero or to a constant.
Often just called all caps null, NULL, but now you should use an null pointer. So, how does this help us? Any time you want to make sure a pointer contains a valid address before you try using it. You test to make sure it's not null first that as you compare it to null pointer. So, what happens if you call delete on a dynamic variable and then you try using the pointers say by dereferencing it to access the data. That leads to another problem. It's sometimes looked at as the cousin of the memory leak and that's called a dangling pointer. So, this is another reason we set the pointer to point to null pointer because it's predictable as a value and we will immediately know that the address doesn't point to anything valid. So, we won't try to do reference it. That's pretty cool. So, we've covered quite a bit in this lecture. Now,
you know how to create data dynamically using new and how to return the memory when you're done using delete. And of course, you know how to set the pointer to null pointer if it won't be used again or until you use it next. Before moving on to the next lecture though, I have a challenge for you. I would like you to continue using this dynamic fun project but I'd like you to try dynamically creating and pointing to boolean data. We haven't used the bool data type as much at least as a variable data type. So, I figured I'd give you a chance to test out your skills. Name the variable, myBool Pointer or myBoolPtr and dynamically point to it. Set its value to true and print the value of the data out. Don't forget to return the memory that was allocated when you're done.
And since it's been while, remember that you can use the boolalpha format flag that comes with iostream with the cout so that it prints out true or false instead of one or zero. So, pause the video and give this one a shot. Come back when you're done or if you need some help. How did your dynamic Boolean pointer challenge go? Let's work on it together. So, below this where we're creating our newInt, I'm going to create a bool pointer myBoolPtr = new bool and we'll use the same technique we're using below myBoolPtr = true. We were told to set it to true. Then, we want to print out the value using boolalpha. So, that will make sure that it prints out true or false instead of zero or one.
All right. And then of course, we want to make sure we return the memory, delete myBool Ptr and to develop good habits will set myBoolPtr to null ptr even though it's at the end of the main. Let's run this to make sure it works. All right, 123 and then we get true. Nice work everyone. So, you can see that we can point to and use dynamically allocated integers and booleans as well. In fact, we can point to any of the types that we've worked with. So, that begs the question. Can dynamically allocated things like arrays and objects that we create on our own, maybe like custom classes. Can we use those? The answer is yes. And that's what we're going to talk about in the next lecture. I'll see you there.
John has a Ph.D. in Computer Science and is a professional software engineer and consultant, as well as a computer science university professor and department chair.