In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article to share with you is about how to deeply understand the C language pointer, Xiaobian feel quite practical, so share to everyone to learn, I hope you can read this article after some harvest, not much to say, follow Xiaobian to see it.
origin
Before I read a sentence on Zhihu, the pointer is the essence of C, and it is also a barrier for beginners. In other words, memory management is the essence of C, C/C++ can deal directly with the OS, from a performance point of view, developers can flexibly allocate and release memory according to their actual use scenarios. Although smart pointers have been introduced in C++ since C++11, although they can be largely avoided, they are still not completely avoided. One of the most important reasons is that you cannot guarantee that other people in the group will not use pointers, and you cannot guarantee that cooperative departments will not use pointers.
So why do pointers exist in C/C++?
This starts with the memory layout of the process.
process memory layout
The above figure shows the memory layout of the 32-bit process. From the above figure, it mainly contains the following blocks:
Kernel space: Used by the kernel, where kernel code and data are stored
stack: This is what we often call a stack, used to store automatic variables
mmap: Also known as a memory map, it is used to allocate address space in the process virtual memory address space and create a mapping relationship with physical memory.
heap: is what we often call heap, dynamic memory allocation is all on heap
bss: Contains all uninitialized global and static variables, all variables in this segment are initialized by 0 or null pointer, program loader allocates memory for BSS segment when loading program
ds: Initialized data block
Contains explicitly initialized global variables and static variables
The size of this segment is determined by the size of the value in the program source code and does not change at runtime
It has read and write permissions, so variable values for this segment can be changed at runtime
This section can be further divided into an initialization read-only area and an initialization read-write area
text: also known as text segment
This section contains the binary file of the compiled program.
This section is a read-only section that prevents the program from being accidentally modified
This segment is shareable, so for frequently executed programs such as text editors, only one copy is needed in memory
Since this article focuses on memory allocation, the following content only relates to stack and heap.
stack
Stack A contiguous block of memory on which memory allocations are performed. The compiler already knows the memory size to allocate when compiling, and when calling the function, its internal traversal allocates memory on the stack; when the function call is terminated, the internal variables are released, and then the memory is returned to the stack.
class Object { public: Object() = default; // ....}; void fun() { Object obj; // do sth}
In the above code, obj is allocated on the stack, and when it is out of the fun scope, it will automatically call the destructor of Object to release it.
As mentioned earlier, local variables are destructed and memory is freed at the end of the scope (such as function scope, block scope, etc.). Because allocation and deallocation are in exactly the opposite order, the FILO feature can be used, and C++ implementations generally use the call stack to allocate local variables (but not the standard requirement).
Because memory allocation and deallocation on the stack is a push and pop process (just a pointer movement process for the compiler), the stack is much faster than memory allocation on the heap.
Although the access speed of stack is faster than heap, each thread has its own stack, and the objects on the stack cannot be accessed across threads, which determines that the stack space is limited. If the stack space is too large, then in large programs, dozens or even hundreds of threads, the light stack space consumes RAM, which leads to the heap available space becoming smaller, affecting the normal operation of the program.
set
On Linux systems, you can view stack size with the following command:
ulimit -s10240
On the author's machine, the output of executing the above command is 10240(KB) or 10m, and the stack size can be modified by shell command.
ulimit -s 102400
The stack space can be temporarily modified to 100m by the above command, which can be done by the following command:
/etc/security/limits.conf Allocation
static allocation
Static allocation is done by the compiler, if local variables and function parameters, etc., are allocated at compile time.
void fun() { int a[10];}
In the above code, a accounts for 10 * sizeof(int) bytes, which is calculated directly at compilation time, and directly pushed into and pulled out of the stack at run time.
dynamic allocation
Many people may think that dynamic allocation exists only on the heap, and only static allocation is possible on the stack. In fact, this view is wrong, the stack also supports dynamic allocation, the dynamic allocation is allocated by the alloca() function. Stack dynamic allocation and heap are different, memory allocated by alloca() function is released by compiler, out of order manual operation.
characteristics
Fast allocation speed: allocation size is done by the compiler in the compiler
No memory fragmentation: stack memory allocation is sequential, pushed and popped in FIFO fashion
Size limitation: Stack size depends on operating system
Restricted access: Access can only be made within the current function or scope
pile
Heap is a form of memory management. Memory management is a very complex business for operating systems because, firstly, memory is large, and secondly, memory requirements are irregular in time and block size (there are dozens or even hundreds of processes running on the operating system, and these processes may request or release memory at any time, and the memory block size requested and released is arbitrary).
Heap this memory management mode is characterized by freedom (at any time to apply, release at any time, size block arbitrary). Heap memory is allocated by the operating system to the heap manager (a piece of code in the operating system, belonging to the memory management unit of the operating system) to manage, the heap manager provides the corresponding interface_sbrk, mmap_, etc., but the interface is often called by the runtime library, that is, the runtime library performs heap memory management, and the runtime library provides the malloc/free function to be called by developers to use heap memory.
distribution methods
As we understand it, since memory allocation is done at runtime and the size of the allocation is not known until runtime, the heap only supports dynamic allocation, and the behavior of memory request and release is operated by the developer itself, which is easy to cause what we call memory leakage.
characteristics
Variable is process-scoped, meaning all threads within a process can access the variable.
There is no memory size limit, this is actually relative, but there is no limit relative to the stack size, in fact, it is ultimately limited to RAM.
Access is slower than stack
memory fragmentation
Memory management by developers, that is, memory application and release are operated by developers
Difference between stack and heap
Understanding the difference between heap and stack will be very useful to us in the development process. Combined with the above content, summarize the difference between the two.
For stack, it is automatically managed by compiler, without manual control; for heap, release work is controlled by programmer, easy to generate memory leak
Space sizes vary
Generally speaking, in 32-bit systems, heap memory can reach 4G space, from this point of view heap memory is almost no limit.
For the stack, there is generally a certain space size, generally depending on the operating system (can also be manually set)
whether or not it can produce fragments differently.
For heap, frequent memory allocation and deallocation will inevitably lead to discontinuity of memory space, resulting in a large number of fragments, which will reduce program efficiency.
For stacks, memory is continuous, and requests and releases are instruction moves, similar to pushing and popping in data structures.
Different growth directions
For the heap, the growth direction is upward, that is, toward the direction of memory address increase.
For the stack, its growth direction is downward, and it grows in the direction of memory address reduction.
Different distribution methods
Heaps are dynamically allocated, such as our common malloc/new, while stacks are statically allocated and dynamically allocated.
Static allocation is done by the compiler, such as allocation of local variables, while dynamic allocation of stacks is done through the alloca() function.
The dynamic allocation of the stack is released by the compiler, while the dynamic allocation of memory on the heap must be released by the developer.
Distribution efficiency varies
The stack has a special register allocated by the operating system to store the address of the stack, and there are special instructions for stack pushing and stack pulling, which determines the stack efficiency.
Heap memory application and release are specially provided by runtime libraries, which involve complex logic, application and release efficiency is lower than stack
Up to this point, the basic characteristics of stack and heap, as well as their respective advantages and disadvantages, use scenarios have been analyzed, here to give developers a suggestion, can use the stack, try to use the stack, on the one hand because the efficiency is higher than the heap, on the other hand, memory application and release by the compiler to complete, so as to avoid a lot of problems.
extended
Finally to this section, in fact, the above said so much, are for this section to do the groundwork.
In the previous content, we compared the stack and heap, although the stack efficiency is relatively high, and there is no memory leak, memory fragmentation, etc., but due to its own limitations (can not be multi-threaded, limited size), so in many cases, still need to be on the heap memory.
Let's start with a code:
#include #include int main() { int a; int *p; p = (int *)malloc(sizeof(int)); free(p); return 0;}
The above code is very simple, there are two variables a and p, the type is int and int *, where a and p are stored on the stack, the value of p is a block address on the heap (in the above code, the value of p is 0x1c66010), the above code layout is shown below:
The above is how to deeply understand the pointer of C language, Xiaobian believes that some knowledge points may be seen or used in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.