[C++] In-depth analysis of new and delete

Article directory

  • 1. What is new/delete?
    • 1.new
    • 2.delete
  • 2. How to use new/delete?
    • 1.new
    • 2.delete
    • 3.new[]
    • 4.[]delete
  • 3. Why new/delete?
    • 1. Why is there operator new/operator delete?
    • 2. Why do we need to use new and delete in a matching manner?

new/delete test environment: visual studio2019 community edition

1. What is new/delete?

In C++ programming, new and delete are operators used to dynamically allocate and release memory. Simply speaking, the best way to apply for and release space in C++ is: new and delete. Since they are operators, they are used new and delete do not require header files.

1.new

new: The new operator is used to dynamically allocate memory to create an object or a memory area, and returns a pointer to the allocated memory. It is used to allocate memory on the heap for use anywhere in the program, not just on the stack. Typically used to create dynamic objects such as class instances.

For example, creating an integer object and allocating memory can be done like this:

int* myInt = new int;

This allocates an integer-sized block of memory on the heap and returns a pointer to that memory.

2.delete

delete: The delete operator is used to free memory previously allocated by new to prevent memory leaks. It deletes the previously allocated memory and sets the pointer to null, preventing access to the freed memory.

For example, to delete previously allocated memory for an integer object, do this:

delete myInt;
myInt = nullptr; // Set the pointer to null to avoid wild pointers

Note: After using new to allocate memory, be sure to use delete to free the memory to avoid memory leaks. Otherwise, the allocated memory will remain on the heap until the program terminates, which may lead to memory resource exhaustion. The best approach is to use smart pointers.

2. How to use new/delete?

1.new

new will apply for a space on the heap and return the address of this space, so it must be received using a pointer type. If the application for space fails, new will throw an exception value.

 Template: Type* T=new Type

Request space for built-in types:

int* mytype = new int

new built-in type note:

1.new will not initialize the space applied for by built-in types, and users need to initialize it themselves.
2. The new built-in type applies for space on the heap. The system will not release the space by itself, so the user needs to use delete to manually release the space.

Request space for a custom type

class A
{<!-- -->
public:
A(int a=1)
{<!-- -->
_a=a;
}
private:
int _a;
};
//new
A* p1 = new A;

New Custom Type Note:

1.new will perform special processing on the space applied for by the custom type, and the constructor of the custom type will be called during the new process.
2. The new custom type applies for space on the heap. The system will not release the space by itself, so the user needs to use delete to manually release the space.

ps: Check the phenomenon of new calling custom type construction

2.delete

Used in conjunction with new to release the space created by new on the heap.

//Type* T=new Type
Template: delete T;

*Release space for built-in types

//int* mytype = new int;
delete mytype;

Note on delete built-in types:

1. The delete behavior at this time is consistent with free(), which simply releases the space opened by new. At this time, there will be no problem if you replace deletet with free.

Free up space for custom types

class A
{<!-- -->
public:
A(int a=1)
{<!-- -->
_a=a;
}
private:
int _a;
};

A* p1 = new A;
//delete
delete p1;

delete built-in type note:

1. Delete at this time will not only release the new space, but also call the destructor of the custom type. The sequence process is to first call the destructor and then release the space.
The phenomenon of ps delete calling custom type destructor

3.new[]

c++ uses new[] to apply for multiple consecutive objects, where [] can specify the number of objects to apply for. If the application fails, an exception value will be thrown.

Template: Type* T = new Type[n]; //Apply for Type array of n objects

Request space for built-in types

int* mytype = new int[10];

new[] built-in type note:

1.new will not initialize the space applied for by built-in types, and users need to initialize it themselves.
2. The new built-in type applies for space on the heap. The system will not release the space by itself, so the user needs to use delete[] to manually release the space.

ps: It can be initialized at the same time when defining.

Request space for a custom type

class A
{<!-- -->
public:
A(int a=1)
{<!-- -->
_a=a;
}
private:
int _a;
};

A* p1 = new A[2]{<!-- -->0, 1};

new[]Custom type note:

1.new[n] will perform special processing on the space applied for by the custom type. During the new process, the constructor of the custom type will be called n times.
2. The new[] custom type applies for space on the heap. The system will not release the space by itself, so the user needs to use []delete to manually release the space.

ps: new[n] calls the constructor phenomenon

4.[]delete

The delete[] function is to release the continuous space applied by new[].

Release space for built-in types

int* mytype = new int[10];
delete []mytype;

[]delete releases the built-in type space. Note:

1. There is no need to specify the number of objects in [] of []delete
2.[]delete must be used in conjunction with new[], otherwise undefined errors may occur.

Free up space for custom types

A* p1 = new A[2]{<!-- -->0, 1};
delete []p1;

[]delete releases custom type space. Note:

1. There is no need to specify the number of objects in [] of []delete
2.[]delete must be used in conjunction with new[], otherwise undefined errors may occur.
3. When using []delete, the destructor of the object will be called, and then the space will be released. The sequence is: first call the destructor and then release the space.

ps:[]delete calls the destructor phenomenon

3. new/delete Why?

1. Why is there operator new/operator delete?

In the previous assembly code, we found that both new and delete call operator new/operator delete
(In vs2019, delete hides the operator delete call), so why is this?

In C++, operator new and operator delete are special functions used for dynamic memory management. These two functions are not overloaded functions, but two special global functions defined by C++ developers. They allow programmers to customize memory allocation and deallocation behavior to meet specific needs. These two operators are usually used together with the keywords new and delete. During the assembly process, new and delete will call operator new/operator delete to open up space and release space.

In fact, the bottom layer of the two functions operator new and operator delete is still implemented using the functions “malloc” and f “ree()” used to apply for and release space in C, operator new and operator delete It is an advanced encapsulated version of “malloc” and “free”, which improves error handling. c++ created operator new and operator delete to better serve the “object-oriented” concept of c++, because the handling of exceptions by “malloc” and “free” is not suitable for the c++ concept, a In a word, the original “malloc” and “free” in C are not easy to use. C++ encapsulates them into operator new and operator delete.

2. Why do we need to match new and delete?

Why do we need to use new and delete, new[] and delete[] differently?

1. Correct memory release: Use new and delete, and the paired use of new[] and delete[] is to ensure correct memory release. Array objects usually require more complex destruction and release procedures, so new[] and delete[] are used.
2. Call the correct destructor: When using new[] to allocate an array, C++ will call the constructor on each array element, and when using delete[] to release the array, it will call the constructor on each array element. The destructor is called on array elements. This ensures that the construction and destruction processes of each object are executed correctly.
3. Avoid undefined behavior: Using new[] and delete[] in pairs can avoid problems caused by undefined memory release behavior. When freeing an array, the system needs to know the size of the array in order to call the object’s destructor one by one.