C語言記憶體管理

来源:https://www.cnblogs.com/latencytime/archive/2018/12/19/10145893.html
-Advertisement-
Play Games

這一節主要講解了C語言里變數在記憶體中的位置,各種變數的使用區別,以及如何在堆棧中分配空間等C語言記憶體管理問題。 自動變數與靜態變數 auto自動變數 auto是預設的關鍵字,如實際中int a,實際為auto int a,{}內部的都是auto變數,不用為此類變數申請或者釋放空間,它都是自動完成的。 ...


         這一節主要講解了C語言里變數在記憶體中的位置,各種變數的使用區別,以及如何在堆棧中分配空間等C語言記憶體管理問題。

自動變數與靜態變數

auto自動變數

    auto是預設的關鍵字,如實際中int a,實際為auto int a,{}內部的都是auto變數,不用為此類變數申請或者釋放空間,它都是自動完成的。

register 變數

   例:register int a = 0;

   要使用register變數必須使用此關鍵字。

static 靜態變數

   記憶體位置在程式執行期間一直不改變,一個代碼的內部靜態變數只能被這個代碼塊內部訪問,函數里使用載入到記憶體時只會初始化一次,每次訪問該函數時不會再初始化。

   例:static int b = 0;   

全局變數與靜態變數

  全局變數的存儲方式與靜態變數相同,可以被多個文件訪問,在{}之外的變數。

例:

 1     //main.c
 2 
 3     int a = 0;  
 4 
 5     Void main{}
 6 
 7    // main1.c
 8 
 9     extern int a;
10 
11      Test(){
12      a…….}

    靜態全局變數:只能在定義它的文件內部訪問,在其它文件外部是不可以被訪問的。

    對於函數在存在靜態函數,表示該函數也只能在文件內部訪問,不可以在文件外部訪問。如果一個代碼塊之外的函數或者變數,C語言都預設是全局的,可以在其它文件被訪問,除非有關鍵字static,靜態函數始終在代碼區,static只表示它對外部是否可見。

    例:static void test()

記憶體佈局

代碼區

    程式被操作系統載入到記憶體的時候,所有的可執行代碼都被載入到代碼區,也叫代碼段,這塊記憶體在運行期間是不可以被修改的,只可以被執行。

靜態區

    所有的靜態變數和全局變數都被放到了靜態區,程式退出的時候消失,在運行期間都占用記憶體。

棧區

     所有的自動變數,函數的形參、返回值都是自動放入棧中,當一個變數超出其作用域時,自動從棧中彈出,不同系統的棧大小是不同的,windows操作系統是棧大小是可以設置的。C語言的形參是從左到右入棧的。

堆區

      堆是一個大容器,它的容量遠遠大於棧,操作也更加複雜。堆中分配的記憶體不會自動釋放,需要用free手動釋放。一個程式的棧大小是有限的, 一個數組太大有可能導致棧溢出,不要在棧裡面定義太大的數組。如果使用一個特別大的數組,那麼使用堆而不是棧;如果一個數組在定義時不確定大小,那麼適合使用堆,不適用棧。Malloc如果分配記憶體不釋放,就會造成記憶體泄漏。Windows操作系統堆每次分配的空間是4k,4K為一頁,優點不用頻繁調度資源,缺點是可能浪費了記憶體。

     void *malloc(int size_t); 

    例:char* =malloc(10);

    Malloc分配空間的初始值是不固定的。

函數返回一個指針

 1 //例1:
 2 int *test(){
 3      Int *p = malloc(1*sizeof(int));//函數不能直接返回一個auto類型的地址
 4      *p = 10;
 5      Return p;
 6    }
 7 // 例2:
 8 const char *test(){
 9        Const char *s = “hello”;
10        Return s;//意思是將s指向一個常量地址,常量在程式運行期間一直都是有效的。常量區和靜態區是有效的,程式運行期間一直有效,但是常量區是只讀的空間。
11 }
12 
13 //例3:
14 const char *test(){
15         Return“hello world”;
16 }

 

堆空間實現動態大小變化的字元數組

 1     //例:
 2          char a[] = “asfsb”;
 3 
 4          char b[] = “jhansdnfsdg”
 5 
 6          char *p = malloc(strlen(a)+strlen(b)+1);
 7 
 8          strcpy(p,a);
 9 
10          strcat(p,b);

calloc與realloc的使用

Void *calloc(size_t nmemb, size_t size)

    Malloc的參數是指定分配的大小,單位是位元組。

    Calloc第一個參數是指定單位的數量,第二個參數指定一個單位的大小。

    例:用malloc分配10個int

    Int *p = malloc(10*sizeof(int));

    用calloc分配10個int

    Int *p = malloc(10,sizeof(int));

    以上兩種寫法分配堆空間的大小是一樣的,malloc只負責分配空間大小,用memset負責清空;Calloc負責分配空間大小,同時負責將空間分配。

    Void *realloc(void *ptr, size_t size)

    Realloc在已分配的空間基礎上,重新擴大或縮小這塊空間。用realloc分配的空間也不會將新改變的空間清空。

通過指針形參分配記憶體的說明

 //例:
void test(char *s){
s =calloc(10,1);
strcpy(s,”hello”);
}//錯誤

void test(char **s){
*s =calloc(10,1);
strcpy(*s,”hello”);
}//正確

   當你想內部給形參分配空間時,形參一定是個二級指針。

   以上便是C語言記憶體管理的基本內容。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、什麼是字典 字典是python里的一種數據類型,特點是元素的無序性,和鍵key的唯一性。字典的創建方法是{key:values},字典里的鍵key只能是不可變的數據類型(整型,字元串或者是元組),值values可以是任何數據類型。字典里的一組key:values叫做一個鍵值對item。 二、字典 ...
  • 函數: 將特定功能代碼編寫在一個函數里 便於閱讀和復用 對一組表達特定功能表達式的封裝 使程式模塊化 python內置函數: input(),print(),eval()... 函數定義 函數語法格式: def <函數名>(<參數列表>): <函數體> return <返回值列表> 函數調用過程: ...
  • 重載運算符 ==和!=的重載 問題:假如有一個類似於vector的類,這個類只能存放string,當有2個這個類的對象時,如何比較這2個對象。 自己重載==和!= 代碼(重載==,!=) c++ include include include class string_vector{ friend ...
  • 初次翻譯,部分內容並非按字面翻譯,是按本人理解進行了內容重組。如有錯誤望指正。 Dart是完全的面向對象的語言,甚至函數也是一個Function類型的對象。這意味著函數可以賦值給變數或者作為函數的參數。你可以直接用變數名(其實現了Function類)作為函數名直接調用。 參考如下示例代碼: 下麵是一 ...
  • 類與類之間的關係 在我們的世界中事物和事物之間總會有一些聯繫. 在面向對象中. 類和類之間也可以產生相關的關係 1. 依賴關係 執行某個動作的時候. 需要xxx來幫助你完成這個操作. 此時的關係是最輕的. 隨時可以更換另外一個東西來完成此操作 2. 關聯關係 在對象裡面埋對象 self.girlFr ...
  • 類與類之間的關係 在我們的世界中事物和事物之間總會有一些聯繫. 在面向對象中. 類和類之間也可以產生相關的關係 1. 依賴關係 執行某個動作的時候. 需要xxx來幫助你完成這個操作. 此時的關係是最輕的. 隨時可以更換另外一個東西來完成此操作 2. 關聯關係 在對象裡面埋對象 self.girlFr ...
  • 1.自動裝箱和自動拆箱 裝箱就是自動將基本數據類型轉換為包裝器類型; (1)Integer it = 200; 實際上是:Integer it3 = Integer.valueOf(100); 自動裝箱功能:把int類型自動裝載到Integer中 先裝箱,再賦值 拆箱就是 自動將包裝器類型轉換為基本 ...
  • 當項目使用分散式架構時,就會有可能出現客戶端數據重覆提交的情況 比如,當你向伺服器發起一個借貸命令時,如果手速夠快,可能會向後臺的兩個撥款伺服器發起同一個請求 此時, 如果不進行處理, 後臺可能會向用戶撥款兩次, 但是用戶只有一次的借錢記錄. 這時, 也是用到了常用sso登錄時的技術Redis, 前 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...