Linux--内存结构
首先看一串代碼
#include <stdio.h> #include <stdlib.h>void main(){int *p1 = (int *)malloc(4);int *p2 = (int *)malloc(4);int *p3 = (int *)malloc(4);int *p4 = (int *)malloc(4);printf("p1 = %p\n",p1);printf("p2 = %p\n",p2);printf("p3 = %p\n",p3);printf("p4 = %p\n",p4); }可見每次開辟的空間之間間隔16字節(p2-p1等于16字節),而每次開辟的空間明明只有4字節,多余的12字節從何而來?
原因在于,malloc開辟的內存空間位于堆,堆是由鏈表維護的,鏈表的每個結點(結構體)由兩部分組成:“數據部分”、“控制部分”。所以對于上面的情況多余的12字節來自于控制部分,并與內存對齊有關。控制部分主要包括上一個結點的地址、下一個結點的地址、當前結點的空間大小等。
在Linux系統中,運行著一個進程,會在"/proc/進程ID"下保存進程運行時所有的信息,進程結束時該文件夾會自動刪除。
Linux的內存結構可以分為以下幾個部分。
代碼段、數據段、BSS段、堆、棧
對于一個空的main函數:
#include <stdio.h> #include <stdlib.h>void main(){}通過size命令查看可執行文件,可以查看代碼段、數據段、BSS段的數據的情況
現在在代碼中插入一個局部常量
#include <stdio.h> #include <stdlib.h> void main(){ const int a = 3; }沒有變化,因為局部常量位于局部棧中。
在代碼中插入一個全局常量
#include <stdio.h> #include <stdlib.h>const int b = 3; void main(){ }代碼段增加了4個字節變成1037,所以全局常量位于代碼段。
查看/proc目錄下進程中的maps文件
總結:
代碼區:存放的CPU的機器指令、全局常量、字符串常量。
數據段:存儲初始化的全局變量、靜態變量。
BSS段:未初始化的全局變量、靜態變量。
堆:動態開辟的內存空間。低地址向高地址擴展
棧:局部變量、局部常量。高地址向低地址擴展
malloc與new的區別:
new的實現是利用malloc,但是在malloc后會初始化空間。
如果是基本數據類型,直接初始化為默認值
如果是UDT,調用對應的構造函數進行初始化。
與內存分配有關的函數:
(1)malloc:
(2)void ?* calloc(int count , int size):count為元素個數,size為每個元素的大小。分配count*size字節的空間,并初始化。
(3)alloca:原型類似malloc,但在棧中分配空間、
(4)void * realloc(void * ptr , int new_size): 修改已經配置好的內存空間大小,ptr為待修改的空間地址,new_size為新的內存大小。?
若內存減少:則直接返回ptr,內存空間大小變為new_size
若內存增加:若后續空間足夠,則返回ptr,內存空間變為new_size。若后續空間不足,則尋找第一個能夠滿足條件的空間,并將數據拷貝到新內存空間,返回新空間地址。
注:ptr = realloc(ptr , new_size)是不對的,如果分配失敗,ptr變為NULL,則原空間不能訪問。
轉載于:https://www.cnblogs.com/xiaogua918/p/4181547.html
總結
以上是生活随笔為你收集整理的Linux--内存结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#如何将线程中的代码抛到主线程去执行
- 下一篇: HDU 2087 (KMP不可重叠的匹配