How C++ performs memory management (new, delete)


introduction

I succeeded because I was determined and never hesitated. — Napoleon 

This chapter is an article about C++ memory management. The words are not many and the content is simple. I hope it will be helpful to you! !

Not much to say, fasten your seat belt, let's start the car (recommended to watch on computer) .


Attachment: red, the part is the key part; the blue color is the part that needs to be memorized (not rote memorization, knock more); black bold or other colors are the secondary key points; black is the description need


mind Mapping:

If you want XMind mind map, you can private message


Table of contents

introduction

1. C/C++ memory distribution

2. Memory management methods in c++ (new, delete)

3. The bottom layer of new and delete

4. The difference between malloc, free and new, delete:


1. C/C++ memory distribution

Knowledge points:

The program memory distribution areas in C/C++ mainly include:
kernel space, stack, heap, memory mapping area, static area (data segment), constant area (code segment).

detail:

1.  The stack is also called the stack -- non-static local variables/function parameters/return values, etc. , and the stack grows downward.
2. The memory-mapped segment is an efficient I/O mapping method for loading a shared dynamic memory bank. Users can use the system interface
to create shared shared memory for inter-process communication. (If you haven't learned this in the Linux course, you just need to understand it now)
3. The heap is used for dynamic memory allocation when the program is running, and the heap can grow upwards.
4. Data segment - store global data and static data .
5. Code segment -- executable code/read-only constant

As shown below:

practise:

//分析下面数据在内存的哪一个区域
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
static int staticVar = 1;
int localVar = 1;
int num1[10] = { 1, 2, 3, 4 };
char char2[] = "abcd";
const char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof(int) * 4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
free(ptr1);
//此处并不需要对ptr2进行释放,因为其指向的空间可能和ptr3一样,释放ptr3即可
free(ptr3);
}

The analysis is as follows:


2. Memory management methods in c++ (new, delete)

Knowledge points:

We have learned how to open up memory (malloc, calloc, realloc) and release memory (free) in C language, but it is not very convenient to use (after we apply, we need to judge whether the application is successful)

Therefore, some changes have been made in c++ to create new. The same principle is to apply for space on the heap, but if the application is not successful at this time, it will directly report an error instead of returning a NULL (this is mainly because c++ is object-oriented. and the C language is procedure-oriented)

detail:

Specific usage (grammar):

  1. type * ptr = new type; (apply for type size space)

delete ptr; (release)

Type * ptr =  new type [n] (apply for n space of type size)

delete[] ptr; (release)

-----------------------------------------------------------------------

  1. Initialize the requested space

Type * ptr =  new w type (n) (initialize the allocated memory to n)

Type * ptr = new type [n]{a,b,c ...} (initialize multiple spaces applied for in sequence as a, b, c .... if not written, initialize to 0)

The comparison between c++ and C language and some more detailed details are as follows in the comments of the code (it is very important to read carefully ):

 #define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>
int main()
{
	//c:
	int* ptr1 = (int*)malloc(sizeof(int));
	free(ptr1);

	//c++:
	int* ptr2 = new int;//此时和上面的申请的空间是一样的其大小也是一个整形的大小
	delete ptr2;//释放也是一样

	//c:
	int* ptr3 = (int*)malloc(sizeof(int) * 10);
	free(ptr3);

	//c++:
	int* ptr4 = new int[10];//此时和上面的申请的空间是一样也是10个整形的大小
	delete[] ptr4;

	//c:
	//malloc不会进行初始化,我们只能另写一个程序进行初始化

	//c++:
	//c++就能直接在申请空间的同时进行初始化工作
	//具体如:
	int* ptr5 = new int(10);//注意这里时圆括号 , 和创建多个对象的方括号不一样
	delete ptr5;

	//对申请多个空间的也能进行初始化
	int* ptr6 = new int[10]{};//用中括号进行初始化,什么都不写时表示申请的空间初始化为0
	delete[] ptr6;

	int* ptr7 = new int[10]{1,2,3};//部分初始化,剩下没写的初始化为0
	delete[] ptr7;

 	A* ptr8 = new A[3];//此处假如A类型没有默认构造的话是不行的,反之则可以
	delete[] ptr8;

	A* ptr9 = new A[3]{1,2,3};//支持隐式类型转换拷贝构造后在构造
	delete[] ptr9;

	A* ptr10 = new A[3]{ A(1),A(2),A(3) };//此时就没有隐式类型转换了,直接进行构造
	delete[] ptr10;

	return 0;
}

practise:

Create node ListCode:

class ListCode
{
public:
	ListCode(int val = 0)
		:val(val)
		,next(nullptr)
	{
	}
private:
	int val;
	struct ListCode* next;
};
int main()
{
	//在C语言数据结构中我们可能还需要去写一个ListCode()的创建节点的函数
	//但此时我们可以直接写成如下模样

	ListCode* n1 = new ListCode(1);//还进行了构造
	ListCode* n2 = new ListCode(2);

	return 0;
}

3. The underlying principle of new and delete

Knowledge points:

The underlying principles of new and delete actually need to call malloc and free , but because of object-oriented reasons, they generally throw exceptions directly, so they need to call a global function before using malloc and free respectively are operator new and operator delete 

Abnormal error message (cannot apply for space at this time):

detail:

  1. Operator new and operator delete functions :    new and delete are operators for users to apply and release dynamic memory , operator new and operator delete are global functions provided by the system , new calls operator new global function at the bottom to apply for space, and delete at the bottom Free up space through the operator delete global function . In fact, operator new and operator delete will call malloc and free, and if they fail, they will recognize it in themselves and report an error message
  2. For custom classes: new and delete actually call constructors and destructors to initialize and destroy the data in them
  3. The order of calling new is: operator new -> constructor, and the calling order of delete is: destructor -> operator delete  , and note that their order cannot be changed , because the destructor needs to release the space requested in the object first Only then can the space borrowed by new be released (conversely, if the new space is released first, the space already applied for by the object will not be found); similarly, for new, you must first apply for space for the object ( Create an object) to apply for other space on the space of the object 
  4. In summary, the following figure is obtained:
  5. For new int[], delete[] ptr they will call operator new[] first and then call n times operator new and n times constructor, delete is similar
  6. Attachment: method of catching exception
    	int* ptr = nullptr;
    	try
    	{
    		do
    		{
    			ptr = new int[1024 * 1024];
    			cout << ptr << endl;
    		} while (ptr);
    	}
    	catch (const exception& e )
    	{
    		cout << e.what() << endl;
    	}
    
    // try 
    //{}
    //catch(const exception& e)
    //{
    //    cout <<e.what()<<endl;
    //}

Attachment: positioning new

Function: Locating the new expression is to call the constructor to initialize an object in the allocated original memory space

Format:  new (place_address) type or new (place_address) type(initializer-list)
place_address must be a pointer, and initializer-list is the initialization list of the type

Uses: It can be used for pooling technology, that is, the operating system will first create a memory pool, which has already applied for a certain amount of space in advance. At this time, we can apply for space more conveniently, instead of applying for it when we need it. In order to apply, the space applied here will naturally not be initialized by the constructor, so we can use the method of positioning new to initialize the applied space

Specific usage method:

int main()
{
    // p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
    A* p1 = (A*)malloc(sizeof(A));
    new(p1)A; // 注意:如果A类的构造函数有参数时,此处需要传参
    p1->~A();
    free(p1);
    return 0;
}

4. The difference between malloc, free and new, delete:

Knowledge points:

  1. First of all, new is created based on the object-oriented situation of c++, so when we cannot apply for space, it will throw an exception, while malloc is process-oriented, and return a null pointer when it cannot apply for space
  2. Secondly, new is faster to write than malloc, it does not need to calculate the type size, and has a more convenient initial method
  3. The last and most important part is that new and delete are created for custom types. They can initialize custom types very well, and they also call constructors and destructors during the process of applying and releasing space
  4. Attachment: malloc and free are functions, new and delete are operators, and the return value of malloc is void*, which must be converted when using it. When malloc fails to apply for space, it returns NULL, so it must be judged as empty when using it.
     

This chapter is over. To predict what will happen next, let's wait for the next chapter to break it down.

If you have any questions, welcome to discuss!

If you think this article is helpful to you, please like it!

Continuously update a large number of C++ detailed content, pay attention early and don't get lost.

Guess you like

Origin blog.csdn.net/ZYK069/article/details/130839589
Recommended