← Back to C++ Course | Chapter 14: Memory Management | Lesson 2 of 6

C++ new & delete

new and delete let you ask for memory while the program runs and give it back when done, like borrowing a table at a restaurant and leaving when finished. You must remember to return it.
Syntax
cpp
data_type *pointer_name = new data_type(value);
delete pointer_name;

data_type *array_name = new data_type[size];
delete[] array_name;

Dynamic Memory Allocation

The new operator requests a block of memory from the heap at runtime and returns a pointer to it, letting you create objects whose size or lifetime isn't known when the program starts.

Every successful new must eventually be paired with a matching delete, or that memory stays reserved for the rest of the program's run -- a memory leak.

Example: Dynamic Memory Allocation

cpp
// Include std::cout and std::cin
#include <iostream>

// Program execution starts in main()
int main() {
	// Allocate an object on the heap with new
	int *ptr = new int(5);
	// Print to the console with cout
	std::cout << *ptr << std::endl;
	// Free the heap memory with delete
	delete ptr;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Dynamic Arrays

delete[] releases memory that was allocated with new[], and must be used instead of a plain delete for arrays -- delete alone only knows how to destroy a single object, not walk through and destruct every element of an array first.

Mismatching new[] with delete (or vice versa) is undefined behavior.

Example: Dynamic Arrays

cpp
// Include std::cout and std::cin
#include <iostream>

// Program execution starts in main()
int main() {
	// Allocate an object on the heap with new
	int *arr = new int[3]{1, 2, 3};
	// Print to the console with cout
	std::cout << arr[1] << std::endl;
	// Free the heap memory with delete
	delete[] arr;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Dynamic Object Creation

new ClassName(args) allocates space for an object and immediately calls its constructor, so the object is fully initialized as soon as the pointer is returned. delete on that pointer runs the destructor first, then frees the underlying memory -- this is how you get RAII-style cleanup even for heap objects.

Example: Dynamic Object Creation

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the type Point
class Point {
// Members below can be accessed from outside the class
public:
	int x;
	Point(int val) : x(val) { std::cout << "Constructed" << std::endl; }
	~Point() { std::cout << "Destructed" << std::endl; }
};

// Program execution starts in main()
int main() {
	// Allocate an object on the heap with new
	Point *p = new Point(5);
	// Print to the console with cout
	std::cout << p->x << std::endl;
	// Free the heap memory with delete
	delete p;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Guarding against Out of Memory

Passing std::nothrow to new (e.g. new(std::nothrow) int[100]) tells it to return a null pointer on allocation failure instead of throwing std::bad_alloc, which is useful in code that can't safely handle C++ exceptions.

You must then check the returned pointer before using it.

Example: Guarding against Out of Memory

cpp
// Include std::cout and std::cin
#include <iostream>
#include <new>

// Program execution starts in main()
int main() {
	int *arr = new(std::nothrow) int[100];
	// Check whether arr == nullptr
	if (arr == nullptr) {
		// Print to the console with cout
		std::cout << "Allocation failed" << std::endl;
	} else {
		// Print to the console with cout
		std::cout << "Allocation succeeded" << std::endl;
	}
	// Free the heap memory with delete
	delete[] arr;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Rules and Memory Leak Protection

Setting a pointer to nullptr immediately after delete prevents a dangling pointer -- one that still holds an address but no longer points to valid memory.

Using or deleting a dangling pointer again is undefined behavior, so this simple habit avoids a whole class of hard-to-debug crashes.

Example: Rules and Memory Leak Protection

cpp
// Include std::cout and std::cin
#include <iostream>

// Program execution starts in main()
int main() {
	// Allocate an object on the heap with new
	int *ptr = new int(5);
	// Free the heap memory with delete
	delete ptr;
	ptr = nullptr;
	// Print to the console with cout
	std::cout << (ptr == nullptr) << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Calling delete twice on the same pointer, which is undefined behavior.
  2. Using delete instead of delete[] for memory allocated with new[].
  3. Not handling a failed allocation, when new throws std::bad_alloc.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.