In C ++ new and delete


1. operator new 、placement new 和 operator delete

We first look at the following simple example

#include <iostream>

class MTestClass
{
public:
	MTestClass(int num) : m_Number(num) {
		std::cout << "执行构造函数 MTestClass(int num)" << std::endl;
	}
	~MTestClass() {
		std::cout << "执行析构函数" << std::endl;
	}

	void print(void) {
		std::cout << "Number is : " << m_Number << std::endl;
	}

private:
	int m_Number = 10;
};

int main(int argc, char** argv)
{
	MTestClass *p = new MTestClass(50);
	p->print();
	delete p;

	system("pause");
	return 0;
}

The above code is very simple,
in the code of our new an object the p- ,
and then call the function p-> Print () ,
and finally delete the object, the Delete the p- ;
above operating results the program is as follows:

The constructor is executed MTestClass (NUM int)
Number The IS: 50
performs destructor

We can make guesses, follow these steps to this process:

  1. In the heap using malloc to create a function sizeof (MTestClass) the size of the memory, and memory into MTestClass * type; (using operator new new )
  2. Call the constructor MTestClass (50) of memory and the setting value assigned. (Use Placement new new )
  3. Calling function p-> print ();
  4. Call the destructor ~ MTestClass ()
  5. The release of the application heap memory space. ( Operator the Delete )
  • new new operator : refers to the form of the form void * operator new (size_t size) in the form of a function allocation size memory size.
  • new new Placement : call the constructor, and has been assigned to the allocated memory, this memory can be a stack memory can also be a heap memory.
    The form :: new new (obj) MTestClass (50) , pointer obj points to memory space existing assignment
  • the Delete operator : release the heap memory space.

We rewrite the above example:

#include <iostream>

class MTestClass
{
public:
	MTestClass(int num) : m_Number(num) {
		std::cout << "执行构造函数 MTestClass(int num)" << std::endl;
	}
	~MTestClass() {
		std::cout << "执行析构函数" << std::endl;
	}

	void* operator new(size_t size) {
		std::cout << "执行 operator new !" << std::endl;
		return ::operator new(size);
	}

	void operator delete(void* pWhere) {
		std::cout << "执行 operator delete !" << std::endl;
		return ::operator delete(pWhere);
	}

	void print(void) {
		std::cout << "Number is : " << m_Number << std::endl;
	}

private:
	int m_Number = 10;
};

int main(int argc, char** argv)
{
	// operator new 
	MTestClass* p = (MTestClass*)MTestClass::operator new(sizeof(MTestClass));
	p->print();

	// placement new 
	::new(p) MTestClass(50);
	p->print();

	// 执行析构函数
	p->~MTestClass();

	MTestClass::operator delete(p);

	system("pause");
	return 0;
}

Run results of the program are as follows:
performing new new operator!
Number The IS: -842 150 451
constructor is executed MTestClass (NUM int)
Number The IS: 50
execute the destructor
performs operator delete!

The results can be seen running,

  1. First, the implementation of operator new new , operator new new although the allocated memory space, but not assigned to this memory space;
  2. Execution Placement new new , call the constructor and assigned to this space.
::new(p) MTestClass(50);
  1. Performing destructor
  2. Execution operator delete frees the memory.

2. new [] sum delete []

We often say that new [] and delete [] must appear in pairs, then why?
In fact, this is, for the common data type using the new [] array created using delete [] , and directly delete the release of the memory effect is the same, for the self-defined types, if the display is declared destructor, you need to use delete [] , if the statement is not displayed destructor, then delete and delete [] the effect is the same.
If the declared destructor, delete [] need to call n times destructor, then delete [] is how to know how many application memory space? We can look at the following pseudo-code

MTestClass *p = new MTestClass[10];
delete[] p;

As follows:
First, new MTestClass [10] will apply 10 * sizeof (MTestClass) + sizeof (size_t) a memory space, why is 10 * sizeof (MTestClass) + sizeof (size_t) months instead of 10 * sizeof (MTestClass) months, because he wants to use sizeof (size_t) number of elements in the array of bytes of storage.
Call delete [] when n times will be to call the destructor accordance with the number of the first byte, and the entire memory space freed.

In order to verify the above statement, we will rewrite the code as follows:

#include <iostream>

class MTestClass
{
public:
	MTestClass(){
		std::cout << "执行构造函数 MTestClass()" << std::endl;
	}
	MTestClass(int num) : m_Number(num) {
		std::cout << "执行构造函数 MTestClass(int num)" << std::endl;
	}
	~MTestClass() {
		std::cout << "执行析构函数" << std::endl;
	}

	void* operator new(size_t size) {
		std::cout << "执行 operator new !" << std::endl;
		return ::operator new(size);
	}

	void operator delete(void* pWhere) {
		std::cout << "执行 operator delete !" << std::endl;
		return ::operator delete(pWhere);
	}

	void* operator new[](size_t size) {
		std::cout << "执行 operator new[] !" << "\tsize is " << size << std::endl;
		return ::operator new[](size);
	}

	void operator delete[](void* pWhere){
		std::cout << "执行 operator delete[] !" << std::endl;
		return ::operator delete[](pWhere);
	}

	void print(void) {
		std::cout << "Number is : " << m_Number << std::endl;
	}

private:
	int m_Number = 10;
	int m_Number2 = 20;
};

int main(int argc, char** argv)
{
	std::cout << sizeof(MTestClass) << ", " << sizeof(size_t) << std::endl;
	MTestClass* p = new MTestClass[5];

	delete[] p;

	system("pause");
	return 0;
}

Run results:
8, 4
perform operator new [] size is 44!
Constructor is executed MTestClass ()
constructor is executed MTestClass ()
constructor is executed MTestClass ()
constructor is executed MTestClass ()
constructor is executed MTestClass ()
performs destructor
destructor performs
execution destructor
performs destructor
performs destructor
performs operator delete []!

As can be seen, operator new new [] memory request size is 44 bytes, the sizeof (MTestClass) is 8 bytes, and sizeof (size_t) is 4 bytes, exactly 44 * 8 + 4 = 5 , to verify the application of space n * sizeof (MTestClass) + sizeof (size_t)

If we do not show declare a destructor, then what will happen? ?
Removing the complete code destructor as follows:

#include <iostream>

class MTestClass
{
public:
	MTestClass(){
		std::cout << "执行构造函数 MTestClass()" << std::endl;
	}
	MTestClass(int num) : m_Number(num) {
		std::cout << "执行构造函数 MTestClass(int num)" << std::endl;
	}

	void* operator new(size_t size) {
		std::cout << "执行 operator new !" << std::endl;
		return ::operator new(size);
	}

	void operator delete(void* pWhere) {
		std::cout << "执行 operator delete !" << std::endl;
		return ::operator delete(pWhere);
	}

	void* operator new[](size_t size) {
		std::cout << "执行 operator new[] !" << "\tsize is " << size << std::endl;
		return ::operator new[](size);
	}

	void operator delete[](void* pWhere){
		std::cout << "执行 operator delete[] !" << std::endl;
		return ::operator delete[](pWhere);
	}

	void print(void) {
		std::cout << "Number is : " << m_Number << std::endl;
	}

private:
	int m_Number = 10;
	int m_Number2 = 20;
};

int main(int argc, char** argv)
{
	std::cout << sizeof(MTestClass) << ", " << sizeof(size_t) << std::endl;
	MTestClass* p = new MTestClass[5];

	delete[] p;

	system("pause");
	return 0;
}

Result of the program:
8, 4
perform operator new [] size is 40!
Constructor is executed MTestClass ()
constructor is executed MTestClass ()
constructor is executed MTestClass ()
constructor is executed MTestClass ()
constructor is executed MTestClass ()
performs operator delete [ ]!

From the results, the size of the application 40 is verified if no declaration destructor display will apply sizeof (MTestClass) * n bytes of memory space, then use the delete and use delete [] effect identical.

By these two examples above may be seen
operator new and operator new [] the effect is the same, is application size space size;
operator Delete and operator delete [] the effect is the same, the release of all heap memory .


Author: douzhq
profile: https://www.douzhq.cn
article synchronization page: https://douzhq.cn/newanddelete/

Published 88 original articles · won praise 79 · views 50000 +

Guess you like

Origin blog.csdn.net/douzhq/article/details/90454467