================================================ ==========================
Click to go directly to the personal homepage: Xiaobai is not a program Yuan
C++ Series Column: C++ Dry Goods Shop
Code repository: Gitee
================================================ ==========================
Table of Contents
Dynamic memory management in C language
What is the difference between malloc/calloc/realloc?
C++ memory management methods
built-in types
Custom type
operator new and operator delete functions
operator new
operator delete
Implementation principles of new and delete
built-in types
The principle of new
The principle of delete
The principle of new T[N]
The principle of delete[]
Positioning new expression (placement-new)
The difference between malloc/free and new/delete
memory leak
What is a memory leak and the dangers of memory leaks
Memory leak classification
How to avoid memory leaks
Dynamic memory management method in C language
Memory allocation function:
malloc/cealloc/realloc
Memory destruction function:
free
int main() { //malloc int* ptr = (int*)malloc(sizeof(int) * 10); free(ptr); //calloc int* ptr2 = (int*)calloc(4, sizeof(int)); //realloc int* ptr3 = (int*)realloc(ptr2, sizeof(int) ); free(ptr3); return 0; }
The difference between malloc/calloc/realloc?
malloc
void* malloc (size_t size);
Allocates a block of memory of size bytes, returning a pointer to the beginning of the block. The contents of the newly allocated memory block are not initialized but retain undefined values. If size is zero, the return value depends on the specific library implementation (it may or may not be a null pointer), but the returned pointer should not be dereferenced.
calloc
void* calloc (size_t num, size_t size);
Allocate a block of memory for an array of num elements, each of which is bytes long, and initialize itsall bits to zero. The effective result is to allocate a zero-initialized block of (num*size)
byte memory. If size is zero, the return value depends on the specific library implementation (it may or may not be a null pointer), but the returned pointer should not be dereferenced.
realloc
void* realloc (void* ptr, size_t size);
Change the size of the memory block pointed to by ptr. Even if a memory block is moved to a new location, the contents of the memory block are retained to the smaller of the old and new sizes. If the new size is larger, the value of the newly allocated portion is undefined. If ptr is a null pointer, this function behaves like malloc, allocating a new block of bytes of size and returning a pointer to its beginning.
More C language dynamic memory functions move here:
Dynamic memory management_Xiaobai is not Program Yuan’s blog-CSDN bloghttps://blog.csdn.net/qq_55119554/article/details/131737338
C++ memory management method
The C language memory management method can continue to be used in C++, but it cannot be used in some places, and it is more troublesome to use, so
This C++ also proposes its own memory management method: dynamic memory management through new and deleteoperators.
built-in type
//Built-in type int main() { //Dynamicly apply for a space of type int int* p = new int; //Destroy dynamically applied space delete p; //Dynamicly apply for a space of type int and initialize it to 0 int* p2 = new int(0); delete p2; //Dynamicly apply for 10 int type spaces int* p3 = new int[10]; delete p3; //Dynamicly apply for 10 int type spaces and initialize the first three elements to 1, 2, 3 and the rest to 0 int* p4 = new int[10] { 1,2,3 }; delete p4; return 0; }
Note:
To apply for and release space for a single element, use the new and delete operators. To apply for and release continuous space, use
new[] and delete[], note: Match them together.
custom type
//Custom type class A { public: A(int a=1) :_a(a) { cout << "A(int a)" << endl; } ~A() { cout << "~A()" << endl; } private: int _a=1; }; int main() { A* ptr = new A; delete ptr; A* ptr2 = new A(0); delete ptr2; A* ptr3 = new A[5]; delete[10] ptr3; A* ptr4 = new A[5]{ 1,2,3 }; delete[5] ptr4; return 0; }
This is the biggest role of new in C++ that is different from malloc in C language: defining a class and being able to initialize it.
Note:
When applying for a custom type space, new will call the constructor, delete will call the destructor, and malloc and
free will not.
operator new and operator delete functions
new and delete are the operators used by users to dynamically memory application and release. Operator new and operator delete are
Global function provided by the system, new calls operator new global function at the bottom to apply for space, delete passes at the bottom
operator delete global function to free up space.
operator new
operator new: This function actually applies for space through malloc, and returns directly when malloc successfully applies for space; apply for space
If it fails, try to implement insufficient space countermeasures. If the countermeasures are set by the user, continue to apply, otherwise an exception will be thrown.
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) { // try to allocate size bytes void *p; while ((p = malloc(size)) == 0) if (_callnewh(size) == 0) { // report no memory // If the application for memory fails, a bad_alloc type exception will be thrown here. static const std::bad_alloc nomem; _RAISE(nomem); } return(p); }
operator delete
operator delete: This function finally releases space through free
void operator delete(void *pUserData) { _CrtMemBlockHeader *pHead; RTCCALLBACK(_RTC_Free_hook, (pUserData, 0)); if (pUserData == NULL) return; _mlock(_HEAP_LOCK); /* block other threads */ __TRY /* get a pointer to memory block header */ pHead = pHdr(pUserData); /* verify block type */ _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); _free_dbg(pUserData, pHead->nBlockUse); __FINALLY _munlock(_HEAP_LOCK); /* release other threads */ __END_TRY_FINALLY return; } /* implementation of free */ #define free(p) _free_dbg(p, _NORMAL_BLOCK)
Through the implementation of the above two global functions, we know that operator new actually uses malloc to apply for space. If
If malloc successfully applies for space, it will return directly. Otherwise, the user-provided response to insufficient space will be executed. If the user provides this measure
Just continue to apply, otherwise an exception will be thrown. operator delete ultimately releases space through free.
The implementation principle of new and delete
Built-in types
If you are applying for a built-in type of space, new is basically similar to malloc, delete and free. The difference is:
new/delete applies for and releases the space of a single element, new[] and delete[] apply for continuous space, and new is applying for
An exception will be thrown when requesting space fails, and malloc will return NULL.
Principle of new
1. Call the operator new function to apply for space
2. Execute the constructor on the requested space to complete the construction of the object
Principle of delete
1. Execute the destructor on the space to complete the cleanup of resources in the object
2. Call the operator delete function to release the object’s space
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 for N object spaces.
2. Execute the constructor N times on the requested space
Principle of delete[]
1. Execute N destructors on the released object space to complete the cleanup of resources in N objects.
2. Call operator delete[] to release space. Actually, operator delete is called in operator delete[] to free up space.
Make space
Let’s try running the above code
Positioning new expression (placement-new)
Concept:
The positioned new expression is to call the constructor to initialize an object in the allocated original memory space.
Use format:
new (place_address) type or new (place_address) type (initializer-list)
place_address must be a pointer, initializer-list is the initialization list of the type
Positioning new expressions are generally used in conjunction with memory pools in practice. Because the memory allocated by the memory pool is not initialized, if
If it is an object of a custom type, you need to use the definition expression of new to explicitly call the constructor for initialization.
Usage scenarios:
class A { public: A(int a = 0) : _a(a) { cout << "A():" <<this << endl; } ~A() { cout << "~A():" <<this << endl; } private: int _a; }; // Position new/replacement new int main() { // p1 now points to a space of the same size as the A object. It cannot be regarded as an object because the constructor does not There is execution A* p1 = (A*)malloc(sizeof(A)); new(p1)A; // Note: If the constructor of class A has parameters, parameters need to be passed here p1->~A(); free(p1); A* p2 = (A*)operator new(sizeof(A)); new(p2)A(10); p2->~A(); operator delete(p2); return 0; }
The difference between malloc/free and new/delete
Common points:
They all apply for space from the heap and require the user to release it manually.
Differences:
- malloc and free are functions, new and delete are operators
- The space requested by mallocwill not be initialized, but new caninitialize
- When malloc applies for space, you need to manually calculate the space size and pass it. New only needs to be followed by the type of space. If there are multiple objects, specify the number of objects in [].
- The return value of malloc is void*, which must be forced when used. Newis not required because new is followed by the type of space.
- When mallocfails to apply for space, itreturns NULL, so it must benull when used, and newis not required. But newneeds to catch exceptions
- When applying for a custom type object, malloc/free will only open up 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< /strong>, delete will call the destructor to complete the cleanup of resources in the space before releasing the space
Memory leak
What is a memory leak and the dangers of a memory leak
What is a memory leak:
A memory leak occurs when a program fails to release memory that is no longer in use due to negligence or error. Memory leaks do not mean the physical disappearance of memory, but that after the application allocates a certain segment of memory, it loses control of the memory segment due to design errors, thus causing a waste of memory.
The dangers of memory leaks:
Memory leaks in long-running programs, such as operating systems, background services, etc., have a great impact. Memory leaks will cause the response to become slower and slower, and eventually freeze.
Memory Leak Classification
In C/C++ programs, we generally care about two aspects of memory leaks:
Heap leak
Heap memory refers to a piece of memory allocated from the heap through malloc / calloc / realloc / new, etc. according to needs during program execution. After use, it must be deleted by calling the corresponding free or delete. If a design error in the program results in this part of the memory not being released, then this part of the space will no longer be able to be used, and a Heap Leak will occur.
System resource leak
It means that the program uses resources allocated by the system, such as sockets, file descriptors, pipes, etc., without using corresponding functions to release them, resulting in a waste of system resources, which can seriously lead to reduced system performance and unstable system execution.
How to avoid memory leaks
1. Establish good design standards in the early stage of the project, develop good coding standards, and remember to release the memory space that matches the application. ps:
this ideal state. But if you encounter an exception, even if you pay attention to the release, problems may still occur. Need next piece of wisdom
It is guaranteed to be managed by pointers.
2. Use RAII ideas or smart pointers to manage resources.
3. Some companies’ internal specifications use internally implemented private memory management libraries. This library comes with built-in memory leak detection options.
4. If something goes wrong, use the memory leak tool to detect it. ps: However, many tools are unreliable or expensive.
To summarize:
Memory leaks are very common and there are two solutions:
1. Preventive type. Such as smart pointers, etc. (Smart pointers, will be discussed later)
2. Check for errors afterwards. Such as leak detection tools.
Today’s sharing ends here! If you think the article is good, you can support it three times in a row. Your support is the driving force for me to move forward!