C++ memory management new and operator new

C++ memory management new and operator new

In C++, we know that functions can be overloaded, and some operators can also be overloaded. Such as the new and delete operators.

We know that new and delete are responsible for applying for memory space and releasing space in C++ . The use and operation of variables with built-in types in the system will not be introduced too much. Let’s take a look at the use of an object today.

First give a simple Test class:

class Test
{
    
    
public:
	Test(int data = 0) : m_data(data)
	{
    
    
		cout << "Create" << endl;
	}
	~Test()
	{
    
    
		cout << "Free" << endl;
	}
private:
	int m_data;
};

There are two cases of new overloading: 1. For a single object. 2. Aimed at array objects.

One, for a single object

First a new object:

	Test* pt = new Test;	//new 操作符(运算符)		1.申请空间   2.构造对象
	Test* pt1 = (Test*)operator new(sizeof(Test));	//相当于malloc  只负责申请空间

	delete pt;	//先调用析构函数,再调用operator delete
	delete pt1;

New and delete after reload

//针对单个对象
void* operator new(size_t sz)
{
    
    
	void* ptr = malloc(sz);
	assert(ptr != nullptr);
	return ptr;
}
void operator delete(void* ptr)
{
    
    
	if (ptr != nullptr)
		free(ptr);
}

The pointer pt points to the object created by the unoverloaded new, and pt1 points to the object created by the overloaded new (operator new). What is the difference between the two?
In fact, the bottom layer of new will call operator new to apply for space for the object first, and then call the constructor of the class to initialize the object. This is why new can initialize variables but malloc cannot.
So when new applies for space:

1. Apply for space
2. Call the constructor to initialize

Similarly, the underlying layer of delete will first call the destructor to clean up the object, and then release the space.
So delete will:

1. Call the destructor
2. Free up space

Note: The order of things that new and delete do should not be messed up. New first applies for space and then calls the constructor, while delete first calls the destructor and then releases the space.

Also note that:
the overloads of new and delete (operator new and operator delete) have two special points:

1. The return value must be void *
2. The parameter type must be size_t

After reloading, new and delete are only responsible for applying and releasing space, and will not call the constructor and destructor

Second, for array objects

	Test* pt2 = new Test[10];

	delete[] pt2;

As in the above code, when applying for an array object, operator new is as follows:

void* operator new[](size_t sz)
{
    
    
	void* ptr = malloc(sz);
	assert(ptr != nullptr);
	return ptr;
}
void operator delete[](void* ptr)
{
    
    
	if (ptr != nullptr)
		free(ptr);
}

In addition to paying attention to the difference with the overloading of ordinary objects. When debugging, we should pay more attention to that for 10 spaces of int size, 4*10 bytes of space should have been applied for, but operator new[] has applied for 44 bytes of space.
Insert picture description here

When operator new[] applies for space, the address of ptr is 0x007e60d8, and the returned pt2 is just 4 bytes (0x007e60dc) more than the address of ptr. The above 4 bytes are not used by users.
Insert picture description here
Why is this? See the explanation below:
Insert picture description here
At the last delete [] pt2, because we released the address of pt2 (0x007e60dc), and ptr (0x007e60dc) is 4 bytes more than pt2, will it cause 4 bytes of memory to leak? , The answer is no. The compiler will be adjusted at the bottom.

Note: But in order to achieve such a situation, the class must have a destructor

Finally, since new is so easy to use, why should we talk about its overloading? We need to understand the difference between overloading and non-overloading: new will call the constructor for initialization in addition to applying for space, but when we need to apply for space When the object of is particularly complex and does not need to be initialized, new calling the constructor will waste time, so we will overload new and only apply for space. Same goes for delete.

Guess you like

Origin blog.csdn.net/qq_43579888/article/details/110501104