<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > C語言程序內存分配

          C語言程序內存分配

          作者: 時間:2016-11-27 來源:網(wǎng)絡 收藏

          (1) 內存分區(qū)狀況

          本文引用地址:http://www.ex-cimer.com/article/201611/322296.htm

          棧區(qū) (stack):

          --分配, 釋放方式: 由編譯器自動分配 和 釋放;

          --存放內容: 局部變量, 參數(shù);

          --特點: 具有 后進先出 特性, 適合用于 保存 回復 現(xiàn)場;

          堆區(qū) (heap):

          --分配, 釋放方式: 由程序員手動 分配(malloc) 和 釋放(free), 如果程序員沒有釋放, 那么程序退出的時候, 會自動釋放;

          --存放內容: 存放程序運行中 動態(tài)分配 內存的數(shù)據(jù);

          --特點: 大小不固定, 可能會動態(tài)的 放大 或 縮小;

          堆區(qū)內存申請:

          --申請過程: OS中有一個記錄空閑內存地址的鏈表, 如果程序員申請內存, 就會找到空間大于申請內存大小的節(jié)點, 將該節(jié)點從空間內存鏈表中刪除, 并分配該節(jié)點;

          --剩余內存處理: 系統(tǒng)會將多余的部分重新放回 空閑內存鏈表中;

          --首地址記錄大小: 分配內存的首地址存放該堆的大小, 這樣釋放內存的時候才能正確執(zhí)行;

          全局區(qū)/靜態(tài)區(qū) (數(shù)據(jù)段 data segment /bss segment):

          --分配, 釋放方式: 編譯器分配內存, 程序退出時系統(tǒng)自動釋放內存;

          --存放內容: 全局變量, 靜態(tài)變量;

          --特點: 全局變量 和 靜態(tài)變量存儲在一個區(qū)域, 初始化的兩種變量 和 未初始化的 存儲在不同區(qū)域, 但是兩個區(qū)域是相鄰的;

          常量區(qū):

          --分配, 釋放方式: 退出程序由系統(tǒng)自動釋放;

          --存放內容: 常量;


          代碼區(qū) (text segment):

          --分配, 釋放方式: 編譯器分配內存, 程序退出時系統(tǒng)自動釋放內存;

          --存放內容: 存放 程序的二進制代碼, 和一些特殊常量;

          內存存放順序 (由上到下): 棧區(qū) -> 堆區(qū) -> 全局區(qū) -> 常量區(qū) -> 代碼區(qū);

          (2) 內存分配方式

          全局內存分配:

          --生命周期: 編譯時分配內存, 程序退出后釋放內存, 與 程序 的生命周期相同;

          --存儲內容: 全局變量, 靜態(tài)變量;

          棧內存分配:

          --生命周期: 函數(shù)執(zhí)行時分配內存, 執(zhí)行結束后釋放內存;

          --特點: 該分配運算由處理器處理, 效率高, 但是棧內存控件有限;

          堆內存分配:

          --生命周期: 調用 malloc()開始分配, 調用 free()釋放內存, 完全由程序員控制;

          --謹慎使用: 如果分配了 沒有釋放, 會造成內存泄露, 如果頻繁 分配 釋放 會出現(xiàn)內存碎片;

          (3) register變量

          使用場景: 如果 一個變量使用頻率特別高, 可以將這個變量放在 CPU 的寄存器中;

          --修飾限制: 只有 局部變量 和 參數(shù) 可以被聲明為 register變量, 全局 和 靜態(tài)的不可以;

          --數(shù)量限制: CPU 寄存器 很寶貴, 不能定義太多register變量;

          (4) extern 變量

          extern變量概念: 聲明外部變量, 外部變量就是在函數(shù)的外部定義的變量, 在本函數(shù)中使用;

          --作用域: 從外部變量定義的位置開始, 知道本源碼結束都可以使用, 但是只能在定義extern后面使用, 前面的代碼不能使用;

          --存放位置: 外部變量 存放在 全局區(qū);

          extern變量作用: 使用extern修飾外部變量, ① 擴展外部變量在本文件中的作用域, ② 將外部變量作用域從一個文件中擴展到工程中的其它文件;

          extern聲明外部變量的情況:

          --單個文件內聲明: 如果不定義在文件開頭, 其作用范圍只能是 定義位置開始, 文件結束位置結束;

          --多個文件中聲明: 兩個文件中用到一個外部變量, 只能定義一次, 編譯 和 連接的時候, 如果沒有這個外部變量, 系統(tǒng)會知道這個外部變量在別處定義, 將另一個文件中的外部變量擴展到本文件中;

          extern編譯原則:

          --本文件中能找到: 編譯器遇到 extern 的時候, 現(xiàn)在本文件中找外部變量的定義的位置, 如果找到, 就將作用域擴展到 定義的位置 知道文件結束;

          --本文件中找不到: 如果本文件中找不到, 連接其它文件找外部變量定義, 如果找到, 將外部變量作用域擴展到本文件中;

          --外部文件找不到: 報錯;

          使用效果: extern 使用的時候, 可以不帶數(shù)據(jù)類型;

          --本文件: int A = 0; 在第10行, extern A 在第一行, 那么A的作用域就擴展為從第一行到文件末尾;

          --多文件: 在任意文件中定義了 int A = 0; 在本文件中聲明 extern A, 那么從當前位置到文件末尾都可以使用該變量;

          (5) static變量 與 全局變量區(qū)別

          static 變量 與 全局變量 相同點: 全局變量是靜態(tài)存儲的, 存儲的方式 和 位置基本相同;

          static 變量 與 全局變量不用點: 全局變量的作用域是 整個項目工程 橫跨過個文件, 靜態(tài)變量的作用域是 當前文件, 其它文件中使用是無效的;

          變量存儲位置: 全局變量 和 靜態(tài)變量 存放在 全局區(qū)/靜態(tài)去, 局部變量存放在 棧區(qū)(普通變量) 和 堆區(qū)(指針變量);

          變量靜態(tài)化:

          --局部變量: 局部變量 加上 static , 相當于將局部變量的生命周期擴大到了整個文件, 作用域不改變;

          --全局變量: 全局變量 加上 static , 相當于將全局變量的作用域縮小到了單個文件, 生命周期是整個程序的周期;

          關于函數(shù)頭文件的引申:

          --內部函數(shù): 單個文件中使用的內部函數(shù), 僅在那個特定文件中定義函數(shù)即可;

          --全局函數(shù): 如果要在整個工程中使用一個全局函數(shù), 需要將這個函數(shù)定義在一個頭文件中;

          static變量與普通變量區(qū)別:

          --static全局變量 與 全局變量區(qū)別: static 全局變量 只初始化一次, 防止在其它文件中使用;

          --static局部變量 與 局部變量區(qū)別: static 局部變量 只初始化一次, 下一次依據(jù)上一次結果;

          static函數(shù)與普通函數(shù)區(qū)別: static 函數(shù)在內存中只保留一份, 普通函數(shù) 每調用一次, 就創(chuàng)建一個副本;

          .

          (6) 堆 和 棧比較

          堆(heap)和棧(stack)區(qū)別:

          --申請方式: stack 由系統(tǒng)自動分配, heap 由程序員進行分配;

          --申請響應: 如果 stack 沒有足夠的剩余空間, 就會溢出; 堆內存從鏈表中找空閑內存;

          --內存限制: stack 內存是連續(xù)的, 從高位向低位擴展, 而且很小, 只有幾M, 是事先定好的, 在文件中配置; heap 是不連續(xù)的, 從低位向高位擴展, 系統(tǒng)是由鏈表控制空閑程序, 鏈表從低地址到高地址, 堆大小受虛擬內存限制, 一般32位機器有4G heap;

          --申請效率: stack 由系統(tǒng)分配, 效率高; heap 由程序員分配, 速度慢, 容易產(chǎn)生碎片;

          (7) 各區(qū)分布情況

          .

          按照下圖分布: 由上到下順序 : 棧區(qū)(stack) -> 堆區(qū)(heap) -> 全局區(qū) -> 字符常量區(qū) -> 代碼區(qū);

          驗證分區(qū)狀況:

          --示例程序:

          [cpp]view plaincopy
          1. /*************************************************************************
          2. >FileName:memory.c
          3. >Author:octopus
          4. >Mail:octopus_work.163.com
          5. >CreatedTime:Mon10Mar201408:34:12PMCST
          6. ************************************************************************/
          7. #include
          8. #include
          9. intglobal1=0,global2=0,global3=0;
          10. voidfunction(void)
          11. {
          12. intlocal4=0,local5=0,local6=0;
          13. staticintstatic4=0,static5=0,static6=0;
          14. int*p2=(int*)malloc(sizeof(int));
          15. printf("子函數(shù)局部變量:");
          16. printf("local4:%p",&local4);
          17. printf("local5:%p",&local5);
          18. printf("local6:%p",&local6);
          19. printf("子函數(shù)指針變量:");
          20. printf("p2:%p",p2);
          21. printf("全局變量:");
          22. printf("global1:%p",&global1);
          23. printf("global2:%p",&global2);
          24. printf("global3:%p",&global3);
          25. printf("子函數(shù)靜態(tài)變量:");
          26. printf("static4:%p",&static4);
          27. printf("static5:%p",&static5);
          28. printf("static6:%p",&static6);
          29. printf("子函數(shù)地址:");
          30. printf("function:%p",function);
          31. }
          32. intmain(intargc,char**argv)
          33. {
          34. intlocal1=0,local2=0,local3=0;
          35. staticintstatic1=0,static2=0,static3=0;
          36. int*p1=(int*)malloc(sizeof(int));
          37. constintconst1=0;
          38. char*char_p="char";
          39. printf("主函數(shù)局部變量:");
          40. printf("local1:%p",&local1);
          41. printf("local2:%p",&local2);
          42. printf("local3:%p",&local3);
          43. printf("const1:%p",&const1);
          44. printf("主函數(shù)指針變量:");
          45. printf("p1:%p",p1);
          46. printf("全局變量:");
          47. printf("global1:%p",&global1);
          48. printf("global2:%p",&global2);
          49. printf("global3:%p",&global3);
          50. printf("主函數(shù)靜態(tài)變量:");
          51. printf("static1:%p",&static1);
          52. printf("static2:%p",&static2);
          53. printf("static3:%p",&static3);
          54. printf("字符串常量:");
          55. printf("char_p:%p",char_p);
          56. printf("主函數(shù)地址:");
          57. printf("main:%p",main);
          58. printf("===============");
          59. function();
          60. return0;
          61. }


          --執(zhí)行結果:

          [cpp]view plaincopy
          1. [root@ip28pointer]#gccmemory.c
          2. [root@ip28pointer]#./a.out
          3. 主函數(shù)局部變量:
          4. local1:0x7fff75f5eedc
          5. local2:0x7fff75f5eed8
          6. local3:0x7fff75f5eed4
          7. const1:0x7fff75f5eed0
          8. 主函數(shù)指針變量:
          9. p1:0x19bad010
          10. 全局變量:
          11. global1:0x600e14
          12. global2:0x600e18
          13. global3:0x600e1c
          14. 主函數(shù)靜態(tài)變量:
          15. static1:0x600e34
          16. static2:0x600e30
          17. static3:0x600e2c
          18. 字符串常量:
          19. char_p:0x4009f7
          20. 主函數(shù)地址:
          21. main:0x40065f
          22. ===============
          23. 子函數(shù)局部變量:
          24. local4:0x7fff75f5eea4
          25. local5:0x7fff75f5eea0
          26. local6:0x7fff75f5ee9c
          27. 子函數(shù)指針變量:
          28. p2:0x19bad030
          29. 全局變量:
          30. global1:0x600e14
          31. global2:0x600e18
          32. global3:0x600e1c
          33. 子函數(shù)靜態(tài)變量:
          34. static4:0x600e28
          35. static5:0x600e24
          36. static6:0x600e20
          37. 子函數(shù)地址:
          38. function:0x400528

          3. 指針與地址


          上一頁 1 2 下一頁

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();