[C++] Pointers

binh12A3
7 min readOct 27, 2021

Hey, my name is pointer, give me your address…😎😎

1. What is pointer ?

int x;
int *ptr:
Where
ptr equivalent &x equivalent address of x
*ptr equivalent x equivalent value of x
  • We can determine type of pointer to a variable by :
#include <iostream>
using namespace std;
int main()
{
int x = 69;
cout << typeid(&x).name() << endl;
}
int*
  • The pointer can’t point to variable which have different datatype (i.e : int pointer can’t point to double variable).
double dValue = 9.0;
int *iPtr = &dValue; //ERROR
  • The pointer stores the address, so it can’t be initialized with an integer
int *ptr = 5; //ERROR
  • The pointer can point to other variales.
  • When accessing to a pointer, the program will access to the pointed memory address then read the value there. For security reason, if the program tries to access to unallocated memory, the OS can stop the program.

NOTE

The size of pointer depends on the architecture on which the execution file is compiled (i.e : x86 = 32bit = 4 bytes, x64 = 64bit = 8 bytes.)

The datatype of pointer doesn’t affect to the size of memory of pointer

2. What is NULL pointer ?

  • Passing “0” to a fucntion which has pointer parameter caused confusing. In C++11 introduced new keyword “nullptr”.

3. Array vs Pointer

  • Array is a collection of continuous memory which are determined by the address of the 1st elelement. And when declare an array, we need to declare its size.
  • Since the array is stored continuously in RAM memory, so we can shift bit to read value of the next element quicly.
  • Value of the array equals the address of the array and equals the address of the 1st element.
  • With pointer, we don’t need to predefine a size, since it could point to uncontinuous memory locations. So it’ll take more time than array. But take less storage than array.
  • We can know the number of elements in array, while we can’t in pointer.
  • When we pass an array to a function, it’ll be implicitly converted to a pointer, even when we pass an array with fixed size.
  • To avoid confusion when manipulating arrays or pointers, it’s recommended to use pointer for a function with array as parameter.
  • Therefore the passing array could be changed ater calling function.

4. Pointer Operations

  • Pointer + 1 : doesn’t return the next memory address but the next memory address of the element which has the same datatype with pointer.
  • We can access an array by pointer, but the array syntax “[]” is preferable since it’s easier.
  • We can loop an array by pointer

5. Dynamic memory allocation

  • For example, we want to define a variable to store a name, but we don’t know the length. We might predict the length and give a “estimated” number to store it.
  • But this way will waste the memory. Normally variables, arrays are stored in “stack” memory location. And the size of stack is pretty small (i.e : 1MB in VisualStudio). If we allocate more than this number, the OS will close this program due to “stack overflow” issue.
  • Since the array has a fixed size so we can’t increase it later (i.e : we have an array of 500 employees, but later company has 600 employees)

That’s why we need Dynamic memory allocation

  • To ask the OS allocates memory when necessary and when the program is running.
  • Use heap memory location (managed by OS). Nowaday, heap can have GB capacity.

5.1 Dynamically allocating variables

  • “new” operator creates the object which uses the memory location, then return that allocated memory location.
  • Normally, to access to the allocated memory, we use pointer to store the returned address by “new” operator.
  • free a memory address (i.e : delete a pointer) could cause many floating pointers. So we should avoid using many pointers point to the same memory location. And after delete, we should assign it to a nullptr.
  • A null pointer doesn’t have any allocated memory, so it’s a good practive to check if it’s a null pointer (not allocated memory) then we’ll allocate it.
  • Memory leak

There are 3 scenarios which could lead to memory leak. And we could prevent it by free the memory (i.e delete ptr) when we go out of range of pointer or before assigning a pointer. (i.e : if the pointer is already allocated, then we just use it, else (i.e: null) we ‘ll allocate new) as above example.

5.2 Dynamically allocating arrays

  • C++ doesn’t have method to change the size of allocated dynamic array. to do that, we need to do Dynamically allocating for a new array. Then copy elements from the old to the new then delete the old. Yes, it’s really complicated , so C++ introduce a special array which could change the size easily, called vector.

6. Pointer to const value

Const Value is normally used in parameters of function when we expect this parameter is read only.

  • Pointer to a const value : is a pointer points to a memory address of constant, it can’t change the value of the pointed memory address, but it can point to another memory address.
  • On the other hand, Const pointer is a constant, so it can’t change the address (can’t point to another memory), but it can change the value at the pointed memory address. A Const pointer need to be initialized when declare, and the assigned address can’t be changed later.
  • A const pointer points to a constant value is a combination of above 2 points. It can’t change both the address and value. (unpopular)

7. Void Pointer

  • We should use void pointer when really needed.
  • void pointer is a general (special) character, which could point to different datatypes, so we can’t determine the datatype of the pointed memory location. Therefore, we need to do a cast, before accessing the value by using “*” operator.
  • We use the void pointer to increase the reusability when we have different types of input.

8. Pointer points to another pointer

  • We just use pointer to pointer when really needed since it’s very complex.
  • Pointer to pointer : is a pointer store the address of the other pointer
  • Pointer to pointer is used to manage the 1-dimensional array of pointes.
  • Pointer to pointer is used to Dynamically allocating of 2-dimensional arrays.
  • Because Dynamically allocating of 2-dimensional arrays as above is complex, so we could use another approach : by using 1 dimension array with size x*y, instead of using 2 dimensional array with x rows, y columns.

9. Functions pointers

  • Function likes a variable which contains a block of code.
  • The nature of the function is an address which stores the the starting place of the block of code.
  • Like the variable, the function is stored in the RAM memory. When the function is called, then the program will goto the address of the function and execute it. Because function has the address, so we can declare a pointer points to a function.
//**NOTE : "()" is mandatory//function pointer has 1 int parameter, return int
int(*funcPtr)(int);
//function pointer has 2 int parameters, return void
void(*funcPtr)(int, int);
  • Like other pointers, Functions pointers must have the defined value before using it.
  • We don’t need to use “&” operator to get the address of a function since C++ handle it implicitly.
  • Functions pointers must have the returned type as same as with the pointed functions.
  • We can call a function via Functions pointers. Note that the default parameters can’t be used via Functions pointer. Because the compiler determines default parameters in the compilation time. While the Functions pointer is used in runtime.
  • We can pass a function as an argument to increase the flexibility.

Instead of having a condition in the function

We can pass Functions pointer as a parameter

  • In C++11, it introduced some new ways to declare a Function pointer

10. Additional notes about pointers

  • The first variable was allocated on the stack. You can call delete only on memory you allocated dynamically (on the heap) using the new operator.
int var, *Ptr;
var = 8; //not dynamically allocated. Can't call delete on it
Ptr = new int; //dynamically allocated. Can call delete on it
  • Setting a pointer to NULL before deleting will cause memory leak.

The following shouldn’t be done:

myPointer = new int;
myPointer = NULL; //leaked memory, no pointer to above int
delete myPointer; //no point at all

You pointed it at NULL before deleting, leaving behind leaked memory (the new int you allocated). There is no way to access that allocated new int anymore, hence memory leak.

The correct way:

myPointer = new int;
delete myPointer; //freed memory
myPointer = NULL; //pointed dangling ptr to NULL

The better way:

If you’re using C++, do not use raw pointers. Use smart pointers instead which can handle these things for you with little overhead.

  • You can delete a pointer if you created it using new. And actually you are deleting an object to which the pointer points, not the pointer itself. Although syntax lets you write delete ptr indeed. But what gets deleted is where ptr points. Not ptr.
  • You can create your own function that does what you want to save your time with pointers
template<typename T>
void deleten(T *&ptr) {
delete ptr;
ptr = NULL;
}

--

--