Article directory
- C/C++ memory management (including the use of new and delete in C++)
C/C++ memory management (including the use of new and delete in C++)
1. C/C++ memory distribution
Let’s first look at the following piece of code and related questions.
int globalVar = 1; static int staticGlobalVar = 1; int main() { 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); return 0; } //1. 选择题: // 选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区) // globalVar在哪里?____ staticGlobalVar在哪里?____ // staticVar在哪里?____ localVar在哪里?____ // num1 在哪里?____ // // char2在哪里?____ *char2在哪里?___ // pChar3在哪里?____ *pChar3在哪里?____ // ptr1在哪里?____ *ptr1在哪里?____ //2. 填空题: // sizeof(num1) = ____; //sizeof(char2) = ____; strlen(char2) = ____; // sizeof(pChar3) = ____; strlen(pChar3) = ____; // sizeof(ptr1) = ____; //3. sizeof 和 strlen 区别? //
- Description:
- stack is also called stack –non-static local variables/function parameters/return values etc. The stack grows downward.
- memory mapped segment is an efficient
I/O
mapping method for loading a shared dynamic memory library. Users can use the system interface to create shared shared memory for inter-process communication. (Linux
If you haven’t learned this in the course, you just need to understand it now)- heap is used for dynamic memory allocation when the program is running, and the heap can grow.
- data segment – Store global data and static data.
- code snippet – Executable code/read-only constants.
So there is an answer to the multiple choice question 1.
Then the answer to 2. Fill in the blank question is: Have you learned it before? Haha.
Part 3.
sizeof
Japanesestrlen
Different?Answer:
strlen
ends when\0
is encountered,strlen
calculates the string length,sizeof
Calculate the size of the variable.
2. Dynamic memory management method in C language: malloc/calloc/realloc/free
malloc
,calloc
andrealloc
are three functions used for dynamic memory allocation in C language. They have some differences, mainly reflected in their Function and usage.
malloc (Memory Allocation, memory allocation):
malloc
It is the abbreviation of "memory allocation" and is used to allocate a memory block of a specified size.- It only allocates memory without initializing it, so the allocated memory may contain arbitrary values.
void* malloc(size_t size);
calloc (Contiguous Allocation, continuous allocation):
calloc
is also a function used to allocate memory, but unlikemalloc
, the memory block allocated bycalloc
will be Initialized to zero.calloc
Accepts two parameters, the required number of elements and the size of each element.void* calloc(size_t num_elements, size_t element_size);
realloc (Re-allocation, reallocation):
realloc
is used toreallocate the size of allocated memory, which can be used to expand or reduce the size of the memory block.- If the address of the original memory block is not empty,
realloc
will try to modify the size of the memory block at the original address (if the new memory size is larger than the original space, you still need to re- allocate memory), if the original address is empty, the behavior is similar tomalloc
.void* realloc(void* ptr, size_t new_size);
Summarize:
malloc
Only a memory block of the specified size is allocated without initialization.calloc
Allocates a memory block of the specified number and size and initializes all bits of the memory block to zero.realloc
Reallocates the size of a memory block, which can be used to expand or shrink the size of allocated memory.
int main() { 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(p2)吗? --- 看情况 free(p3); return 0; }
3. C++ dynamic memory management
The C language memory management method can continue to be used in C++, but there are some places where it cannot be used (such as initializing objects), and it is more troublesome to use. Therefore,C++ has proposed its own Memory management method: dynamic memory management through new and delete operators.
3.1. New/delete operation built-in types
int main() { // 动态申请一个int类型的空间 int *ptr4 = new int; // 动态申请一个int类型的空间并初始化为10 int *ptr5 = new int(10); cout << *ptr5 << endl; // 动态申请10个int类型的空间 int *ptr6 = new int[3]; // 动态申请10个int类型的空间并初始化前3个 int *ptr7 = new int[3]{ 1, 2, 3}; cout << ptr7[0] << ptr7[1] << ptr7[2] << ptr7[3]; delete ptr4; delete ptr5; delete[] ptr6; delete[] ptr7; }
- initialization format:
- Single element space:
new 类型 (初始化值)
- Continuous space:
new 类型 [元素个数] {从前往后元素初始化值,其余元素初始化为0}
- Note: To apply for and release the space of a single element, use the
new
anddelete
operators to apply for and release For continuous spaces, usenew[]
anddelete[]
. Note: is matched using .
3.2. New/delete operation custom type
class Date { public: Date() : _year(1), _month(1), _day(1) { cout << "Date()" << endl; } Date(int year, int month, int day) : _year(1), _month(1), _day(1) { _year = year; _month = month; _day = day; cout << "Date()" << endl; } ~Date() { cout << "~Date()" << endl; } private: int _year; int _month; int _day; }; int main() { Date *ptr1 = new Date(); Date *ptr2 = new Date(2, 2, 2); Date *ptr3 = new Date[10]{ { 1, 2, 2}}; free(ptr1); delete ptr2; delete[] ptr3; return 0; }
- initialization format:
- Single element space:
new 类型 (初始化值)
- Continuous space:
new 类型 [元素个数] {从前往后元素初始化值使用{}代表每一个元素的值,其余元素初始化为0}
new/delete
The biggest difference between andmalloc/free
is thatnew/delete
for [custom type] in addition to opening space, the constructor and destructor will also be called。
4. operator new and operator delete functions
new
anddelete
are the operators for users to apply for and release dynamic memory.operator new
andoperator delete
are provided by the system. Global functions,new
call global functions at the bottom layer to apply for space, a> global function. through the bottom layerFree space at theoperator new
delete
operator delete
operator new
: This function actually applies for space throughmalloc
, and returns directly whenmalloc
successfully applies for space; fails to apply for space, and attempts to implement insufficient space countermeasures , if the user has set the countermeasure, continue to apply, otherwise an exception will be thrown.operator delete
is finally released throughfree
.class Date { public: Date() : _year(1), _month(1), _day(1) { cout << "Date()" << endl; } Date(int year, int month, int day) : _year(1), _month(1), _day(1) { _year = year; _month = month; _day = day; cout << "Date()" << endl; } ~Date() { cout << "~Date()" << endl; } private: int _year; int _month; int _day; }; int main() { //operator new -- 不调用构造函数 和 malloc 基本一样 Date *ptr6 = (Date *) operator new(sizeof(Date)); delete new(ptr6) Date; ptr6 = nullptr; return 0; }
5. Implementation principles of new and delete
5.1. Built-in types
If you are applying for a built-in type of space,
new
andmalloc
,delete
andfree
Basically similar, the difference is:new
/delete
applies for and releases the space of a single element,new[]
anddelete[]
Apply for continuous space, andnew
will throw an exceptionwhen the space application fails,malloc
will returnNULL
.
5.2. Custom type
new
principle
- Call
operator new
function to apply for space- Execute the constructor on the requested space to complete the construction of the object
delete
principle
- Execute the destructor on the space to complete the cleanup of resources in the object
- Call
operator delete
function to release the object’s space
new T[N]
principle
calls
operator new[]
function, and actually calls function inoperator new[]
to complete Application for object spaceoperator new
N
Execute the constructor
N
times on the requested space
delete[]
principle
Execute the destructor on the released object space
N
times to complete the cleanup of resources in N objectsCall
operator delete[]
to release space, actually call inoperator delete[]
to release spaceoperator delete
Here we need to pay attention to a phenomenon: For built-in types, when
new T[N]
, the memory space opened is often larger thanN*sizeof(T)
, which may be more Out4
bytes.Originally the space size opened here
ptr2
should be12*10 = 120
, but here it shows124
, where4
bytes are used to store the number of open consecutiveDate
objects.class Date { public: Date() : _year(1), _month(1), _day(1) { cout << "Date()" << endl; } Date(int year, int month, int day) : _year(1), _month(1), _day(1) { _year = year; _month = month; _day = day; cout << "Date()" << endl; } ~Date() { cout << "~Date()" << endl; } private: int _year; int _month; int _day; }; int main() { Date* ptr1 = new Date; delete ptr1; Date* ptr2 = new Date[10]; delete[] ptr2; return 0; }
But if it is a built-in type
new T[N]
, no additional space is needed to store the number.Originally the space opened here should be, and it is displayed here, that is, there is no space to store the number.
ptr3
size
4*10 = 40
40
class Date { public: Date() : _year(1), _month(1), _day(1) { cout << "Date()" << endl; } Date(int year, int month, int day) : _year(1), _month(1), _day(1) { _year = year; _month = month; _day = day; cout << "Date()" << endl; } ~Date() { cout << "~Date()" << endl; } private: int _year; int _month; int _day; }; int main() { Date* ptr1 = new Date; delete ptr1; Date* ptr2 = new Date[10]; delete[] ptr2; int* ptr3 = new int[10]; delete[] ptr3; return 0; }
reason: The extra
4
bytes are used to record the number of continuous spaces ofT
size opened, so as to facilitate < a i=3> perform destruction and release space.delete []
If you do not write a destructor here (the default member variables do not open up space, if you open up space, you must call the destructor to release the space, otherwise memory leaks will occur), then no error will be reported, because the member variables are all built-in types There is no open space, no need to call the destructor, and there is no need to add
4
the number of bytes in front, that is, the custom typenew T[N]
can be directly a>delete
, the same is true for built-in types.class Date { public: Date() : _year(1), _month(1), _day(1) { cout << "Date()" << endl; } Date(int year, int month, int day) : _year(1), _month(1), _day(1) { // _a = new int[10]; _year = year; _month = month; _day = day; cout << "Date()" << endl; } // ~Date() { // cout << "~Date()" << endl; // } private: // int* _a; int _year; int _month; int _day; }; int main() { Date *ptr1 = new Date; delete ptr1; Date *ptr2 = new Date[10]; // 这里如果不写析构函数(默认成员变量没有开辟空间,如果开辟了空间,必须调用析构函数释放空间,不然会内存泄露)的话就不报错 // 因为成员变量都是内置类型没有开空间,不需要调用析构函数,也就不需要在前面添加4字节存个数 delete ptr2; return 0; }
Originally the size of the space allocated here
ptr2
should be12*10 = 120
, and it is displayed here120
, that is, there is no allocated space. Number of objects.
6. Position new expression (placement-new)
The positioning new expression is to call the constructor to initialize an object in the allocated original memory space.
- Used case:
new (place_address) type
or personnew (place_address) type(initializer-list)
place_address
must be a pointer,initializer-list
is the initialization list of the type- Usage scene:
- Positioning
new
Expressions generally match in practicememory poolUse. Because the memory allocated by the memory pool is not initialized, if it is a custom type object, you need to use the definition expression ofnew
to explicitly call the constructor for initialization.class Date { public: Date() : _year(1), _month(1), _day(1) { cout << "Date()" << endl; } Date(int year, int month, int day) : _year(1), _month(1), _day(1) { _year = year; _month = month; _day = day; cout << "Date()" << endl; } ~Date() { cout << "~Date()" << endl; } private: int _year; int _month; int _day; }; int main() { Date *p = (Date *) operator new(sizeof(Date)); // 不能显式调用构造函数 // p->Date(); // 定位new可以显式调用构造函数 new(p)Date(1, 1, 1); p->~Date(); return 0; }
OKOK, that’s it for C/C++ memory management. If you are also interested in Linux and C++, you can check out my homepage. Below is my github homepage, which records my learning code and solutions to some problems of leetcode. If you are interested, you can take a look.