Variables declared normally live on the stack and are destroyed automatically when they go out of scope. new allocates an object on the heap instead, which lives until it is explicitly freed with delete. new returns a pointer to the allocated object:

int* ptr = new int;
delete ptr;

The allocated object can be given an initial value:

int* ptr = new int(1);
std::cout << *ptr << "\n";  // 1
delete ptr;

Class objects are allocated the same way and their constructor is called with the given arguments. delete calls the destructor before freeing the memory:

struct Point {
  Point(int x, int y) : x(x), y(y) {}
  int x;
  int y;
};

Point* p = new Point(1, 2);
std::cout << p->x << "\n";  // 1
delete p;

Arrays are allocated with new[] and must be freed with delete[]:

int* arr = new int[3];
arr[0] = 1;
delete[] arr;

Caution

Every new must be matched with exactly one delete, and every new[] with exactly one delete[]. Mixing them, deleting twice, or using the pointer after deleting it is undefined behaviour.

Forgetting to delete is a memory leak. The memory stays allocated until the program exits:

void leak() {
  int* ptr = new int(1);
}  // ptr goes out of scope but the int is never freed.

Array elements can be initialised with values:

int* arr = new int[3]{1, 2, 3};

References