3️C++

C++ 程序编译过程

The compilation process is divided into four processes: compilation (compilation preprocessing, compilation, optimization), assembly, and linking.

Compile preprocessing: process instructions beginning with #;

Compile and optimize: translate the source code .cpp file into .s assembly code;

Assembly: translate assembly code .s into machine instruction .o file;

Link: The object file generated by the assembler, that is, the .o file, will not be executed immediately, because it may appear that a function in the .cpp file refers to a symbol defined in another .cpp file or calls a library file. The function. The purpose of the link is to connect the target files corresponding to these files into a whole, so as to generate an executable program .exe file.

C++ 内存管理

C++ memory partitions: stack, heap, global/static storage area, constant storage area, code area.

Stack: store local variables, function parameters, return addresses, etc. of the function, which are automatically allocated and released by the compiler.

Heap: The dynamically applied memory space is the memory block allocated by malloc, and its allocation and release are controlled by the programmer. If the program execution has not been released, the operating system will automatically reclaim it.

Global area/static storage area (.bss section and .data section): store global variables and static variables, and the operating system will automatically release the program after running. In C language, the uninitialized ones are placed in the .bss section, and the initialized ones are placed in the In the .data section, no distinction is made in C++.

Constant storage area (.data section): Stores constants, which cannot be modified, and will be released automatically after the program runs.

Code area (.text section): store code, not allowed to modify, but can be executed. The compiled binaries are stored here

栈和堆的区别

Application method: the stack is automatically allocated by the system, and the heap is actively applied by the programmer.

System response after application: allocate stack space, if the remaining space is larger than the application space, the allocation is successful, otherwise the allocation fails and the stack overflows; apply for heap space, and the way the heap is presented in memory is similar to a linked list (a linked list that records free address space), in the linked list Search for the first node larger than the application space and assign it to the program, and delete the node from the linked list. In most systems, the first address of the block space stores the size of the allocated space for easy release. The remaining space is connected to the free list again.

The stack is a continuous piece of space in memory (extends to low addresses), the maximum capacity is predetermined by the system, and the space in the heap in memory (extends to high addresses) is discontinuous.

Application efficiency: the stack is automatically allocated by the system, and the application efficiency is high, but the programmer cannot control it; the heap is actively applied by the programmer, which is inefficient and convenient to use but prone to fragmentation.

Stored content: local variables and function parameters are stored in the stack; the content stored in the heap is controlled by the programmer.

变量的区别

The difference between global variables, local variables, static global variables, and static local variables:

C++ variables have different scopes according to the different life cycles of the defined locations. The scopes can be divided into six types: global scope, local scope, statement scope, class scope, namespace scope and file scope.

From the perspective of scope:

Global variables: have global scope. Global variables only need to be defined in one source file, and they can be applied to all source files. Of course, other source files that do not contain global variable definitions need to declare this global variable again with the extern keyword.

Static global variables: have file scope. The difference between it and global variables is that if the program contains multiple files, it acts on the file where it is defined, and cannot affect other files, that is, variables modified by the static keyword have file scope. In this way, even if two different source files define static global variables with the same name, they are different variables.

Local variables: have local scope. It is an automatic object (auto), which does not exist all the time during the running of the program, but only exists during the execution of the function. After a call of the function is executed, the variable is canceled and the memory it occupies is also recovered.

Static local variables: have local scope. It is only initialized once, and it exists from the first time it is initialized until the end of the program. The difference between it and the global variable is that the global variable is visible to all functions, while the static local variable is always only for the function body that defines itself visible.

From the allocation of memory space:

Static storage area: global variables, static local variables, static global variables.

Stack: local variables.

什么是内存泄露

memory leak: The failure of a program to free memory that is no longer in use, due to inadvertence or error.

It does not mean that the memory disappears physically, but that the program loses control of the memory due to negligence or errors during the running process, resulting in a waste of memory.

It often refers to heap memory leaks, because the heap is dynamically allocated and controlled by the user. If used improperly, memory leaks will occur.

When using malloc, calloc, realloc, new, etc. to allocate memory, call the corresponding free or delete to release the memory after use, otherwise this memory will cause a memory leak.

Pointer reassignment

At the beginning, the pointers p and p1 respectively point to a memory space, but the pointer p is reassigned, so that the memory space initially pointed to by p cannot be found, and a memory leak occurs.

智能指针有哪几种?智能指针的实现原理?

Smart pointers are proposed to solve memory leaks caused by dynamic memory allocation and to release the same memory space multiple times. In C++11, it is encapsulated in the < memory > header file.

Smart pointers in C++11 include the following three types:

Shared pointer (shared_ptr): The resource can be shared by multiple pointers, and the usage counting mechanism indicates that the resource is shared by several pointers. Check the number of resource owners through use_count(), which can be constructed through unique_ptr and weak_ptr, call release() to release the ownership of the resource, and the count will be reduced by one. When the count is reduced to 0, the memory space will be automatically released, thus avoiding memory leak.

Exclusive pointer (unique_ptr): A smart pointer with exclusive ownership, the resource can only be occupied by one pointer, and the pointer cannot be copied and assigned. However, move construction and move assignment construction (calling the move() function) can be performed, that is, one unique_ptr object is assigned to another unique_ptr object, and assignment can be made through this method.

Weak pointer (weak_ptr): points to the object pointed to by shared_ptr, which can solve the circular reference problem caused by shared_ptr.

一个 unique_ptr 怎么赋值给另一个 unique_ptr 对 象?

With the help of std::move(), one unique_ptr object can be assigned to another unique_ptr object, the purpose of which is to realize the transfer of ownership.

std::unique_ptr ptr1(new A());

std::unique_ptr ptr2 = std::move(ptr1);

使用智能指针会出现什么问题?怎么解决?

Possible problems with smart pointers: circular references

In the following example, two classes Parent and Child are defined, and the shared pointer of the object of the other class is defined in the two classes respectively. After the program ends, the two pointers point to each other's memory space, resulting in the memory cannot be released.

The solution to circular references: weak_ptr

Circular reference: The called destructor is not called, resulting in a memory leak.

weak_ptr has a non-owning (weak) reference to the object managed by shared_ptr, which must be converted to shared_ptr before accessing the referenced object;

weak_ptr is used to break the circular reference problem of the object managed by shared_ptr. If this ring is isolated (there is no external shared pointer pointing to the ring), the reference count of shared_ptr cannot reach 0, and the memory is leaked; let one of the pointers in the ring be Weak pointers can avoid this situation;

weak_ptr is used to express the concept of temporary ownership. When an object only needs to be accessed when it exists, and may be deleted by others at any time, you can use weak_ptr to track the object; when you need to obtain ownership, convert it to

Last updated