char *buffer = new char[size]
allocates memory for a character array of length "size" on the heap, and it saves a pointer to it in the variable "buffer".
When you no longer need the array, you have to call delete[] buffer
. By doing this, you free the memory, so other parts of your code can reuse it.
If you forget to delete the buffer after using it, the memory is still allocated, and no one else can use it. This is called a memory leak. If you do that often enough, there will be no more memory left, it's all filled up with data you're no longer using.
Because programmers often forget to call delete[]
, smart pointers were introduced. When you assign a pointer to a smart pointer, the smart pointer will automatically delete the pointer when it goes out of scope.
Consider the following functions:
#include <memory>
void good() {
std::unique_ptr<char[]> p{new char[2]()};
}
void medium() {
char *p = new char[2]();
delete[] p;
}
void bad() { // memory leak!
char *p = new char[2]();
}
And here's what they compile to:
good():
sub rsp, 8
mov edi, 2
call operator new[](unsigned long) ; <-------------------
xor edx, edx
mov WORD PTR [rax], dx
mov rdi, rax
add rsp, 8
jmp operator delete[](void*) ; <-------------------
medium():
sub rsp, 8
mov edi, 2
call operator new[](unsigned long) ; <-------------------
xor edx, edx
mov WORD PTR [rax], dx
mov rdi, rax
add rsp, 8
jmp operator delete[](void*) ; <-------------------
bad():
mov edi, 2
jmp operator new[](unsigned long) ; <-------------------
Ignore the mov, xor, sub and add instructions, just focus on the call and jump instructions.
The medium function is what you would do in old C++: you manually call new and delete.
The bad function only calls new, so the memory is never freed, and you get a memory leak.
The good function uses a smart pointer: as you can see, in the C++ code, only new is called, but if you look at the compiled version, you can see that delete is called at the end of the function! The smart pointer cleans up the memory for you, automatically.
Pieter