Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Understanding Pointers and Heap Memory | Introduction to Smart Pointers
C++ Smart Pointers

Understanding Pointers and Heap MemoryUnderstanding Pointers and Heap Memory

What is a pointer

Pointers are an essential concept in the world of C++. Instead of storing actual data, pointers store memory addresses, allowing developers to efficiently access and manipulate various parts of the memory.

Note

You can think of pointers as GPS coordinates. They point us to specific locations in the memory, and allow us to access data stored in those locations.

When you declare a pointer, you create a variable that holds the memory address of another variable. For example, you can create a pointer to an integer like this:

  • ptr holds the memory address of the integer myValue.
  • The & sign is used to get the memory address of the variable it’s used with.
  • &myValue retrieves the memory address of the myValue variable, which is then stored in the ptr pointer.

Null pointers

In C++, null or nullptr are special keywords used to represent a null pointer. A null pointer *doesn't point to any valid memory address. It's essentially a pointer with no target.

Note

We can also initialize the integer pointer to null (or nullptr). We do this when we don't want to associate the pointer with a specific value right away.

Reassigning pointers

Pointers can be reassigned:

Pointer arithmetic

Pointer arithmetic is a fascinating aspect of pointers. It allows you to traverse memory by incrementing or decrementing the address held by a pointer.

For example, consider the following code where we create an array of integers and then define a pointer to hold the address of the array. Since an array contains multiple elements, a pointer, by default, stores the address of the first element, which in this case is the integer 1.

To access the second element, we can simply increment the pointer by 1. Then, we finally dereference it using the (*) operator. Derefencing returns the value present at the memory address held by the pointer (the integer 2 in our case). Follow the comments in the above code to know what’s happening!

Dynamic memory allocation

There are two kinds of memory available for use in a C++ program: stack and heap. Stack memory is limited in size. It’s well-suited for small, short-lived variables that aren’t needed beyond their scope. When a variable on the stack goes out of scope, it’s automatically destroyed.

However, when you need memory that persists longer than its scope, or requires more space, you turn to the heap. The heap is a much larger pool of memory where your program can request memory at runtime. This is typically done using the new keyword:

Here, we've allocated memory for an integer on the heap and stored its address in a pointer. The tricky thing about heap memory is that it’s not automatically released. It’s the developer’s responsibility to deallocate it when they are done. For every new, there must be a corresponding delete.

Memory leaks and dangling pointers

When you introduce pointers into your C++ code, you enter the realm of manual memory management. Manual memory management requires you to release the memory when it's no longer needed. It can lead to common pitfalls: memory leaks and dangling pointers.

Memory leaks

Memory leaks typically occur when you forget to deallocate memory. Such memory remains reserved, causing your program to lose memory over time.

Example

You create dynamic objects in a loop, but never delete them, they will lead to a memory leak.

Dangling pointers

Dangling pointers occur when a pointer continues to point to a memory that’s been deallocated. It's like having a treasure map that leads you to a place (memory address) where the treasure (data) has already been taken (destroyed).

cpp

main.cpp

In the above code, we try to access a pointer after calling delete on it, which deallocates the memory it was pointing to. After deletion, the pointer becomes a dangling pointer, as it still holds the address to a memory that no longer exists.

Accessing a dangling pointer can lead to unpredictable behavior or even crashes, as the memory it points to is no longer valid. To avoid dangling pointers, it’s important to set a pointer to “null” after calling delete on it. Then, before accessing the value of that pointer, it’s imperative to check whether it’s null or not. Consider the following code:

cpp

main.cpp

Does the following code have a memory leak?

Selecione a resposta correta

Tudo estava claro?

Seção 1. Capítulo 1
course content

Conteúdo do Curso

C++ Smart Pointers

Understanding Pointers and Heap MemoryUnderstanding Pointers and Heap Memory

What is a pointer

Pointers are an essential concept in the world of C++. Instead of storing actual data, pointers store memory addresses, allowing developers to efficiently access and manipulate various parts of the memory.

Note

You can think of pointers as GPS coordinates. They point us to specific locations in the memory, and allow us to access data stored in those locations.

When you declare a pointer, you create a variable that holds the memory address of another variable. For example, you can create a pointer to an integer like this:

  • ptr holds the memory address of the integer myValue.
  • The & sign is used to get the memory address of the variable it’s used with.
  • &myValue retrieves the memory address of the myValue variable, which is then stored in the ptr pointer.

Null pointers

In C++, null or nullptr are special keywords used to represent a null pointer. A null pointer *doesn't point to any valid memory address. It's essentially a pointer with no target.

Note

We can also initialize the integer pointer to null (or nullptr). We do this when we don't want to associate the pointer with a specific value right away.

Reassigning pointers

Pointers can be reassigned:

Pointer arithmetic

Pointer arithmetic is a fascinating aspect of pointers. It allows you to traverse memory by incrementing or decrementing the address held by a pointer.

For example, consider the following code where we create an array of integers and then define a pointer to hold the address of the array. Since an array contains multiple elements, a pointer, by default, stores the address of the first element, which in this case is the integer 1.

To access the second element, we can simply increment the pointer by 1. Then, we finally dereference it using the (*) operator. Derefencing returns the value present at the memory address held by the pointer (the integer 2 in our case). Follow the comments in the above code to know what’s happening!

Dynamic memory allocation

There are two kinds of memory available for use in a C++ program: stack and heap. Stack memory is limited in size. It’s well-suited for small, short-lived variables that aren’t needed beyond their scope. When a variable on the stack goes out of scope, it’s automatically destroyed.

However, when you need memory that persists longer than its scope, or requires more space, you turn to the heap. The heap is a much larger pool of memory where your program can request memory at runtime. This is typically done using the new keyword:

Here, we've allocated memory for an integer on the heap and stored its address in a pointer. The tricky thing about heap memory is that it’s not automatically released. It’s the developer’s responsibility to deallocate it when they are done. For every new, there must be a corresponding delete.

Memory leaks and dangling pointers

When you introduce pointers into your C++ code, you enter the realm of manual memory management. Manual memory management requires you to release the memory when it's no longer needed. It can lead to common pitfalls: memory leaks and dangling pointers.

Memory leaks

Memory leaks typically occur when you forget to deallocate memory. Such memory remains reserved, causing your program to lose memory over time.

Example

You create dynamic objects in a loop, but never delete them, they will lead to a memory leak.

Dangling pointers

Dangling pointers occur when a pointer continues to point to a memory that’s been deallocated. It's like having a treasure map that leads you to a place (memory address) where the treasure (data) has already been taken (destroyed).

cpp

main.cpp

In the above code, we try to access a pointer after calling delete on it, which deallocates the memory it was pointing to. After deletion, the pointer becomes a dangling pointer, as it still holds the address to a memory that no longer exists.

Accessing a dangling pointer can lead to unpredictable behavior or even crashes, as the memory it points to is no longer valid. To avoid dangling pointers, it’s important to set a pointer to “null” after calling delete on it. Then, before accessing the value of that pointer, it’s imperative to check whether it’s null or not. Consider the following code:

cpp

main.cpp

Does the following code have a memory leak?

Selecione a resposta correta

Tudo estava claro?

Seção 1. Capítulo 1
some-alt