[C++ Introduction] new and delete (C/C++ memory management)

1. C/C++ memory distribution

Let's look at a small problem first:

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);
	free(ptr3);
}


question:

Here is the quote

Let's briefly analyze it below:

The first globalVaris a global variable, followed staticGlobalVarby a static global variable, which staticVaris a static local variable, all in the static area (data segment). The last localVaris a local variable, num1which is an integer array, so they are on the stack.

char2This character array is also on the stack, but it is initialized with the constant string of the code segment (constant area), and then, it is the *char2address char2of the first element of the array, that *char2is, the first element of the array, which is also on the stack. pChar3It is a local pointer variable on the stack, but pChar3it points to a constant string in the constant area, so *pChar3it is in the constant area. ptr1It is also a local pointer variable. On the stack, ptr1the space pointed to is malloced and on the heap.

insert image description here

Let's look at a few more questions:

Here is the quote
sizeof(num1), num1 is an integer array of 10 elements, and the array name sizeofrepresents the entire array inside, so the answer is 40; sizeof(char2), there are 5 characters in char2 (the string hides the end mark \0), so the answer is 5; strlen(char2)Find the length of the string , is 4; sizeof(pChar3), the pointer variable, the size is 4 or 8 bytes; strlen(pChar3), the same length is 4; sizeof(ptr1), the pointer variable, 4 or 8 bytes.

Let's take a look at the C/C++ memory area division:

Please add a picture description

illustrate:

  1. The stack is also called the stack – non-static local variables/function parameters/return values, etc., the stack grows downward
  2. Memory-mapped segments are efficient I/O mappings for loading a shared dynamic memory bank. Users can use the system interface to create shared shared memory for inter-process communication
  3. The heap is used for dynamic memory allocation when the program is running, and the heap can grow upwards
  4. Data segment – ​​stores global and static data
  5. Code Segment – ​​executable code/read-only constants

2. Dynamic memory management in C language

Let's take a brief look at the memory management method in C language:

void Test()
{
    
    
	int* p1 = (int*)malloc(sizeof(int));
	free(p1);
	// 1.malloc/calloc/realloc的区别是什么?
	int* p2 = (int*)calloc(4, sizeof(int));
	int* p3 = (int*)realloc(p2, sizeof(int) * 10);
	free(p3);
}


malloc和callocBoth of them can open up memory space on the heap. Except for the difference in passing parameters, the difference between the two is that calloc will initialize all the opened space to 0, while malloc will not initialize. realloc can be expanded (there are two ways, one is in-situ expansion and the other is remote expansion).

3. C++ memory management method

The C language memory management method can continue to be used in C++, but there are some places where it can’t be done, and it is more troublesome to use, so C++ has proposed its own memory management method:Dynamic memory management through new and delete operators

3.1 new/delete operation built-in type

In C language:

When we use it malloc/callocto apply for space, we need to calculate the size of the space we need to open up, and then pass the parameters. What about the return value void*, we need to force it ourselves.
insert image description here

Then in C++ we can do this:

Here is the quote
Using an operator here new, we don't need sizeof to calculate the size, we can directly give the type, and there is no need for mandatory type conversion.

The same dynamic application for 10 integer-sized spaces:

Here is the quote

C++ creates new and delete more for custom types, so new and delete operate custom types, which we will explain later. In addition, the space created by the built-in type new is not initialized, but C++ actually has a way to initialize the space created by new:
insert image description here
The picture above is to dynamically apply for an int type size space and initialize it to 10

Can we initialize an array that we create dynamically using new?
it is also fine:insert image description here

Let's look at another one newthat "supports" the operator delete:

malloc/callocTo use the space opened up on the heap in C language, you need to use free to release it.
Then in C++, we newneed to use an operator called the space we came out of delete:
insert image description here
the same use of new dynamic array destruction:
insert image description here
Note deletethe square brackets after
insert image description here

Notice:match up and use
To apply and release space for a single element, use new and delete operators, apply and release continuous space, use new[] and delete[]

3.2 new and delete operation custom type

We mentioned above: C++ new和deleteis used more for custom types, so let's take a look at what is special about new and delete for custom types.

Let's take a simple example:

class A
{
    
    
public:
	A(int a = 0)
		: _a(a)
	{
    
    
		cout << "A():" << this << endl;
	}
	~A()
	{
    
    
		cout << "~A():" << this << endl;
	}
private:
	int _a;
};

What is the difference between the following two ways of writing:
insert image description here

Using malloc just opens up space. In addition to opening up space with new, the constructor is automatically called for initialization. Free just releases the space; delete not only releases the space pointed to by the pointer, but also calls the destructor to destruct the custom type.
insert image description here
insert image description here

Summarize:
When applying for and releasing space of a custom type, new will automatically call the constructor, delete will automatically call the destructor, and malloc and free will not

4. operator new and operator delete functions

Although the function names of these two functions are operator operators, operator new and operator delete are not overloads of new and delete.operator new and operator delete are two global functions in the library

Here 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. space .

Let's take a look at their underlying implementation:

Here is the quote
Operator new actually uses malloc to apply for space. If the application is successful, it will return directly. If the application fails, an exception will be thrown.

insert image description here
operator delete actually uses free to release space

Through the implementation of the above two global functions, we know that,operator new actually applies for space through malloc. If malloc successfully applies for space, it will return directly. Otherwise, it will execute the countermeasures provided by the user for insufficient space. If the user provides this measure, it will continue to apply, otherwise it will throw an exception. operator delete finally releases space through free

5. Implementation principle of new and delete

5.1 Built-in types

If you apply for a built-in type of space, new and malloc, delete and free are basically similar, the difference is: new/delete applies for and releases the space of a single element, new[] and delete[] apply for continuous space, Moreover, new will throw an exception when it fails to apply for space, and malloc will return NULL

5.2 Custom types

  1. The principle of new
  1. Call the operator new function to apply for space, and operator new actually calls malloc
  2. Execute the constructor on the requested space to complete the construction of the object
  1. The principle of delete
  1. Execute the destructor on the object space to be released to complete the cleanup of resources in the object
  2. Call the operator delete function, operator delete actually calls free to release the space of the object
  1. The principle of new T[N]
  1. Call the operator new[] function, and actually call the operator new function in operator new[] to complete the application of N object spaces
  2. Execute the constructor N times on the requested space
  1. The principle of delete[]
  1. Execute N times of destructors on the object space to be released to complete the cleanup of resources in N objects
  2. Call operator delete[] to release space, actually call operator delete in operator delete[] to release space

6. The difference between malloc/free and new/delete

What malloc/free and new/delete have in common is that they all apply for space from the heap and need to be released manually by the user.
The differences are:

  1. malloc and free are functions, new and delete are operators
  2. The space requested by malloc will not be initialized, but new can be initialized
  3. When malloc applies for space, you need to manually calculate the size of the space and pass it on. New just needs to follow it with the type of space. If there are multiple objects, specify the number of objects in []
  4. The return value of malloc is void*, which must be forced when used, and new does not need it
  5. When malloc fails to apply for space, it returns NULL, so it must be judged as empty when using it.
  6. When applying for a custom type of object, malloc/free will only open up and release space, and will not call the constructor and destructor, while new will call the constructor to complete the initialization of the object after applying for space, and delete will call the parser before releasing the space. The constructor completes the cleanup of resources in the space

7. Position new expression (understand)

Positioning the new expression is to call the constructor to initialize an object in the allocated original memory space.
Usage format:
new (place_address) type or
new (place_address) type(initializer-list)
place_address must be a pointer, and initializer-list is a parameter list.
In practice, positioning new expressions are generally used with memory pools.
Because the memory allocated by the memory pool is not initialized, if it is an object of a custom type, it needs to use positioning new to explicitly call the constructor for initialization.

Guess you like

Origin blog.csdn.net/weixin_69423932/article/details/132532505