C/C++ memory management, malloc, realloc, calloc, new, delete detailed explanation! ! !

1. Preliminarily understand the data characteristics stored in each interval in the memory

1. Stack area: stores some local variables, function parameters, return values, etc., which are related to the function stack vibration. When it goes out of scope, the life cycle ends.

2. Heap area: used to dynamically open up space. If the space is not actively destroyed, the program will end and the life cycle will end.

3. Data segment (static area): static variables and global variables modified by static. The program ends and the life cycle ends.

4. Code segment (constant area): executable code and constants.

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

  choice : A .   B . bank   C . Several steps ( Jingping district )   D ) Jōryoku(Daiko Dan .
  globalVar Are you here? __1__   staticGlobalVar Are you here? __2__
  staticVar Are you here? __3__   localVar Are you here? __4__
  num1 Are you here? __5__
  char2 Are you here? __6__   * char2 Are you there? __7_
  pChar3 Are you here? __8__       * pChar3 Are you there? __9__
  ptr1 Are you here? __10__         * ptr1 Are you here? __11__
1.C       2.C       3.C        4. A       5.A       
6.A        7. A       8.A        9.D        10.A        11.B
From the above figure, we can know that cha2 itself is stored in the stack area, the pointer points to the address of the first element of the array in the stack area, and then "abcd" in the static area is assigned to the array, so the element pointed to by *char is in the stack area! ! !
pChar3 itself is stored in the stack area, pointing to the first address where the "abcd" string is stored in the static area! ! !

2.C language implements memory management

2.1malloc

Open a space on the heap that matches your expected size and return a pointer to the address space

void* malloc (size_t size);

size: How much space to open, in bytes

2.2realloc

If the space opened by malloc is less, realloc can reopen a space on the heap that matches your expected size and return a pointer to the space.

void* realloc (void * ptr,size_t size);

ptr: address of initial space

size: How large is the space to open up?

 2.3calloc

Used to initialize the opened space, calloc will initialize each element in the opened space to 0

void* realloc (size_t num,size_t size);

num: the number of elements allocated

size: size of each element

3.C++ implements memory management

3.1 new/delete new []/delete []

In C++, there are two pairs of operators new/delete and new []/delete []. Their role is to open and release space! ! !

The function of new is similar to malloc, and the function of delete is similar to free.

new and delete will call the constructor and destructor when facing a custom type

new = apply for object space first and then call the constructor

delete = call the destructor first and then release the object space

3.1.1 Built-in types

When you need to open a plastic space.

int main()
{ 
	//malloc
	int* p1 = (int*)malloc(sizeof(int));
	//new开空间用法跟malloc不同,但是作用相同,都是负责开空间!!!
	int* p2 = new int;

	//free
	free(p1);
	//delete
	delete(p2);
	return 0;
}

When you need to open multiple spaces, such as 10 int type spaces, you need to add []

int main()
{
	int* p1 = (int*)malloc(sizeof(int)*10);
	int* p2 = new int[10];

	free(p1);
	delete[](p2);
	return 0;
}
3.1.2 Custom types

new and delete will call the constructor and destructor when facing a custom type

new = open space first and then call the constructor

delete = call the destructor first and then release the space

class Stack
{
public:
	Stack(int capacity = 4)
	{
		_a = new int[capacity];
		int _top = 0;
		int _capacity = capacity;
	}
	~Stack()
	{
		delete (_a);
		_a = nullptr;
		_top = 0;
		_capacity = 0;
	}
private:
	int* _a;
	int _top;
	int _capacity;
};
int main()
{
	Stack* p2 = new Stack;
	//new先开空间 再去调用构造函数
	delete(p2);
	//delete先调用析构函数,再去释放空间
	return 0;
}

If you need to open 10 Stack type spaces, use new[] and delete[]

int main()
{
	Stack* p2 = new Stack[10];
	//new先开空间 再去调用构造函数
	delete[](p2);
	//delete先调用析构函数,再去释放空间
	return 0;
}

 3.2New/delete underlying implementation principle

3.2.1 Global function operator new/operator delete

To know the principle, we must first know the two global functions operator new / operator delete

In C++, there are two global functions. Their functions are similar to malloc and free. They are responsible for opening and releasing space! ! !

Note: operator new / operator delete are not overloads of new/delete, but two global functions! ! !

We know that when malloc fails to apply for space, it will return empty. When operator new fails to apply for space, an exception will be thrown. We can understand that operator is an encapsulated malloc.

In other words, operator new and mclloc have the same usage and functions except for the different handling methods of failure to apply for space! ! !

operator delete can be understood as corresponding to operator new, and its usage and function are exactly the same as free! ! !

int main()
{
	Stack* p1 = (Stack*)malloc(sizeof(Stack));
	free(p1);
	 
	//operator new底层用的是malloc
	Stack* p2 = (Stack*)operator new (sizeof(Stack));
	//operator delete底层用是free
	operator delete(p2);
	return 0;
}
3.2.2 The relationship between new/delete and operator new/operator delete

new = 1. Apply for object space + 2. Call constructor

delete = 1. Call destructor + 2. Release object space

In terms of underlying principles, the first step for new to apply for the object space is to call the operator new function.

The second step of operator to release the underlying object space is to call operator operator function.

In other words, the following two different pieces of code have the same effect. 

int main()
{
	Stack* p1 = new Stack;
	delete (p1);
	
    //等价于new
	Stack* p2 = (Stack*)operator new (sizeof(Stack));
	//定位new显示调用构造函数
	new(p2)Stack;
    //等价于delete
	p2->~Stack();
	operator delete(p2);
	return 0;
}

Let’s prove it from the perspective of assembly language

Guess you like

Origin blog.csdn.net/qq_73955920/article/details/134439280