datastructure_c_malloc_memory
'''
写在前面的话,本来想学习下数据结构,查半天说用C有利于理解内存释放什么,学生狗当然不怕折腾(虽然大部分说数据结构和算法学思想,和语言无关--||),看了列表什么的当然用C写一下啊,然后发现malloc什么的忘了,折腾半天想搞清楚malloc怎么实现运行的,这下好了,一发不可收拾了。
'''
- Memory:
- Memory management is the heart of operating systems; it is crucial for both programming and system administration.
- While the concepts are generic, examples are mostly from Linux and Windows on 32-bit x86.
- Each process in a multi-tasking OS runs in its own memory sandbox(wiki link). This sandbox is the virtual address space, which in 32-bit mode is always a 4GB block of memory addresses.
- These virtual addresses are mapped to physical memory by page tables(wiki link), which are maintained by the operating system kernel and consulted by the processor.
- Each process has its own set of page tables, but there is a catch. Once virtual addresses are enabled, they apply to all softwarerunning in the machine, including the kernel itself.Thus a portion of the virtual address space must be reserved to the kernel:
- This does not mean the kernel uses that much physical memory, only that it has that portion of address space available to map whatever physical memory it wishes.
- In Linux, kernel space is constantly present and maps the same physical memory in all processes. Kernel code and data are always addressable, ready to handle interrupts or system calls at any time. By contrast, the mapping for the user-mode portion of the address space changes whenever a process switch happens:
- Blue regions represent virtual addresses that are mapped to physical memory, whereas white regions are unmapped.
- The distinct bands in the address space correspond to memory segments like the heap, stack, and so on. Keep in mind these segments are simply a range of memory addresses and have nothing to do with Intel-style segments.
- When computing was happy and safe and cuddly, the starting virtual addresses for the segments shown above were exactly the same for nearly every process in a machine. This made it easy to exploit security vulnerabilities remotely.
- Stack:
-
- The topmost segment in the process address space is the stack, which stores local variables and function parameters in most programming languages. Calling a method or function pushes a new stack frame onto the stack. The stack frame is destroyed when the function returns. This simpe design, possible because the data obeys strict LIFO order, means that no complex data structure is needed to track stack contents – a simple pointer to the top of the stack will do.
- It is possible to exhaust the area mapping the stack by pushing more data than it can fit. This triggers a page fault that is handled in Linux by expand_stack(), which in turn calls acct_stack_growth() to check whether it’s appropriate to grow the stack. If the stack size is below RLIMIT_STACK (usually 8MB), then normally the stack grows and the program continues merrily, unaware of what just happened.
- However, if the maximum stack size has been reached, we have a stack overflow and the program receives a Segmentation Fault.
- Dynamic stack growth is the only situation in which access to an unmapped memory region, shown in white above, might be valid. Any other access to unmapped memory triggers a page fault that results in a Segmentation Fault. Some mapped areas are read-only, hence write attempts to these areas also lead to segfaults.
- The topmost segment in the process address space is the stack, which stores local variables and function parameters in most programming languages. Calling a method or function pushes a new stack frame onto the stack. The stack frame is destroyed when the function returns. This simpe design, possible because the data obeys strict LIFO order, means that no complex data structure is needed to track stack contents – a simple pointer to the top of the stack will do.