Professional C__ - Marc Gregoire [12]
Some C++ compilers actually do support the preceding declaration, but this syntax is currently not part of the C++ specification. Most compilers offer a “strict” mode that will turn off these nonstandard extensions to the language.
To allocate an array dynamically, you first need to declare a pointer:
int* myVariableSizedArray;
The * after the int type indicates that the variable you are declaring refers to some integer memory in the heap. Think of the pointer as an arrow that points at the dynamically allocated heap memory. It does not yet point to anything specific because you haven’t assigned it to anything; it is an uninitialized variable.
To initialize the pointer to new heap memory, you use the new command:
myVariableSizedArray = new int[arraySize];
This allocates memory for enough integers to satisfy the arraySize variable. Figure 1-3 shows what the stack and the heap both look like after this code is executed. As you can see, the pointer variable still resides on the stack, but the array that was dynamically created lives on the heap.
FIGURE 1-3
Now that the memory has been allocated, you can work with myVariableSizedArray as though it were a regular stack-based array:
myVariableSizedArray[3] = 2;
When your code is done with the array, it should remove it from the heap so that other variables can use the memory. In C++, you use the delete command to do this.
delete [] myVariableSizedArray;
The brackets after delete indicate that you are deleting an array!
The C++ commands new and delete are similar to malloc() and free() from C. The syntax of new and delete is simpler because you don’t need to know how many bytes of memory are required.
In C++, every call to new or new[] should be paired with a call to delete or delete[] to prevent memory leaks. Similarly, every call to malloc() should be paired with a call to free(). Memory leaks are discussed in Chapter 21.
To avoid common memory problems, you should use smart pointers instead of normal pointers. Smart pointers will automatically deallocate memory when the smart pointer object goes out of scope. Instead of writing the following:
int* myVariableSizedArray = new int[arraySize];
You should use the C++11 unique_ptr defined in the unique_ptr This unique_ptr version does not require you to deallocate the memory; it will be deallocated automatically when the unique_ptr pointing to that memory goes out of scope. You can use the myVariableSizedArray smart pointer the same way as a normal pointer. Smart pointers are discussed in detail in Chapter 21, but as the preceding example showed, they are very easy to use and highly recommended as a replacement for normal pointers to avoid certain memory problems. Working with Pointers There are other reasons to use heap memory besides dynamically allocating arrays. You can put any variable in the heap by using a similar syntax: int* myIntegerPointer = new int; In this case, the pointer points to the address of just a single integer value. To access this value, you need to dereference the pointer. Think of dereferencing as following the pointer’s arrow to the actual value in the heap. To set the value of the newly allocated heap integer, you would use code like the following: *myIntegerPointer = 8; Notice that this is not the same as setting myIntegerPointer to the value 8. You are not changing the pointer; you are changing the memory that it points to. If you were to reassign the pointer value, it would point to the memory address 8, which is probably random garbage that will eventually make your program crash. A pointer must be valid before dereferencing it. A null or uninitialized pointer will cause a crash if dereferenced. Pointers don’t always point to heap memory. You can declare a pointer that points to a variable on the stack, even another pointer. To get a pointer to a variable, you use the & “address of” operator: int i = 8; int* myIntegerPointer = &i; // Points