欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言深入講解棧與堆和靜態(tài)存儲區(qū)的使用

 更新時間:2022年04月18日 11:14:33   作者:清風自在 流水潺潺  
對大多數(shù)C 語言初學者來說,堆棧卻是一個很模糊的概念。堆棧是一種數(shù)據(jù)結(jié)構(gòu),一個在程序運行時用于存放的地方,相信這可能是很多初學者共同的認識,靜態(tài)存儲區(qū)即內(nèi)存在程序編譯的時候就已經(jīng)分配好,這塊內(nèi)存在程序的整個運行期間都存在

一、程序中的棧

  • 棧是現(xiàn)代計算機程序里最為重要的概念之一
  • 棧在程序中用于維護函數(shù)調(diào)用上下文
  • 函數(shù)中的參數(shù)和局部變量存儲在棧上

 棧保存了一個函數(shù)調(diào)用所需的維護信息

  • 參數(shù)
  • 返回地址
  • 局部變量
  • 調(diào)用上下文

二、函數(shù)的調(diào)用過程

每次函數(shù)調(diào)用都對應(yīng)著一個棧上的活動記錄

  • 調(diào)用函數(shù)的活動記錄位于棧的中部
  • 被調(diào)函數(shù)的活動記錄位于棧的頂部

三、函數(shù)調(diào)用的棧變化

從main() 開始運行

 main() 調(diào)用 f()

 當從 f() 調(diào)用中返回 main()

四、函數(shù)調(diào)用棧上的數(shù)據(jù)

  • 函數(shù)調(diào)用時,對應(yīng)的??臻g在函數(shù)返回前是專用的
  • 函數(shù)調(diào)用結(jié)束后,??臻g將被釋放,數(shù)據(jù)不再有效

        下面看一個指向棧數(shù)據(jù)的指針: 

#include <stdio.h>
 
int* g()
{
    int a[10] = {0};
    return a;
}
 
void f()
{
    int i = 0;
    int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *pointer = g();
    
    for (i = 0; i < 10; i++)
    {
        b[i] = pointer[i];
    }
    for(i = 0; i < 10; i++)
    {
        printf("%d\n", b[i]);
    } 
}
 
int main()
{
    f();
    return 0;
}

         輸出結(jié)果如下:

        如果把 

        for (i = 0; i < 10; i++)

       {

                b[i] = pointer[i];

       }

        注釋了,直接打印 pointer[i] 里面的數(shù)據(jù),如下:

#include <stdio.h>
 
int* g()
{
    int a[10] = {0};
    return a;
}
 
void f()
{
    int i = 0;
    int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *pointer = g();
    /*
    for (i = 0; i < 10; i++)
    {
        b[i] = pointer[i];
    }
    */
    for(i = 0; i < 10; i++)
    {
        printf("%d\n", pointer[i]);
    } 
}
 
int main()
{
    f();
    return 0;
}

        輸出結(jié)果如下:

         為什么直接打印 pointer[i] 里面的值會是這樣呢?因為 pointer 指向的空間是??臻g,??臻g在 g() 函數(shù)返回之后,活動記錄就被釋放了。被釋放后調(diào)用 printf 函數(shù),printf 函數(shù)需要在棧上面建立一個活動記錄。這個活動記錄就會有 printf 函數(shù)的參數(shù)信息和返回值等,所以 pointer 所指向的內(nèi)存里面的數(shù)據(jù)由于 printf 函數(shù)的調(diào)用被改變了。因此,不能返回局部變量的地址,不能返回局部數(shù)組的數(shù)組名。

五、程序中的堆

  • 堆是程序中一塊預(yù)留的內(nèi)存空間,可由程序自由使用
  • 堆中被程序申請使用的內(nèi)存在被主動釋放前將一直有效

        為什么有了棧還需要堆?

        答:棧上的數(shù)據(jù)在函數(shù)返回后就會被釋放掉,無法傳遞到函數(shù)外部,如:局部數(shù)組

C語言程序中通過庫函數(shù)的調(diào)用獲得堆空間

  • 頭文件:malloc.h
  • malloc -- 以字節(jié)的方式動態(tài)申請堆空間
  • free -- 將堆空間歸還給系統(tǒng)

系統(tǒng)對堆空間的管理方式

空閑鏈表法,位圖法,對象池法等等

        以 int* p = (int*)malloc(sizeof(int)); 為例,要申請 4 個字節(jié)的大小,遍歷之后發(fā)現(xiàn)跟 5 Bytes 這個節(jié)點最接近,找到一個可以用的單元之后,就將這個單元的地址返還給了 p 指針。以前也提過使用 malloc 申請內(nèi)存空間時返回的內(nèi)存空間可能比申請的實際內(nèi)存空間要大一點點,原因就是在空閑鏈表管理堆空間這樣的系統(tǒng)里面,它會找最近的那個,找到后的一般都大于等于所需要的內(nèi)存空間,假如 5 Bytes 這個節(jié)點下所有的空閑內(nèi)存單元都用完的話,就會找 12 Bytes 節(jié)點下的內(nèi)存單元,這樣malloc 返回的內(nèi)存空間就有可能比自己實際申請的內(nèi)存空間要大。

六、程序中的靜態(tài)存儲區(qū)

  • 靜態(tài)存儲區(qū)隨著程序的運行而分配空間
  • 靜態(tài)存儲區(qū)的生命周期直到程序運行結(jié)束
  • 在程序的編譯期靜態(tài)存儲區(qū)的大小就已經(jīng)確定
  • 靜態(tài)存儲區(qū)主要用于保存全局變量和靜態(tài)局部變量
  • 靜態(tài)存儲區(qū)的信息最終會保存到可執(zhí)行程序中

        下面看一個靜態(tài)存儲區(qū)的驗證代碼:

#include <stdio.h>
 
int g_v = 1;
 
static int g_vs  = 2;
 
void f()
{
    static int g_vl = 3;
    
    printf("%p\n", &g_vl);
}
 
int main()
{
    printf("%p\n", &g_v);
    
    printf("%p\n", &g_vs);
    
    f();
    
    return 0;
}

        輸出結(jié)果如下:

         可以看到這三個地址是順序存放的,因為這三個變量都是存放在程序的靜態(tài)存儲區(qū),靜態(tài)存儲區(qū)在程序里面有固定的起始地址。 

七、小結(jié)

棧,堆和靜態(tài)存儲區(qū)是程序中的三個基本數(shù)據(jù)區(qū)

  • 棧區(qū)主要用于函數(shù)調(diào)用的使用
  • 堆區(qū)主要是用于內(nèi)存的動態(tài)申請和歸還
  • 靜態(tài)存儲區(qū)用于保存全局變量和靜態(tài)變量

到此這篇關(guān)于C語言深入講解棧與堆和靜態(tài)存儲區(qū)的使用的文章就介紹到這了,更多相關(guān)C語言 棧與堆內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言中的程序環(huán)境與預(yù)處理詳情

    C語言中的程序環(huán)境與預(yù)處理詳情

    這篇文章主要介紹了C語言中的程序環(huán)境與預(yù)處理詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07
  • 詳解C++異常處理機制示例介紹

    詳解C++異常處理機制示例介紹

    任何東西都可以認為是異常,錯誤只是異常的一種。本文將帶大家了解C++中異常是什么,是如何捕獲和處理的等相關(guān)知識。文中示例代碼簡潔易懂,感興趣的小伙伴可以了解一下
    2022-08-08
  • C語言實現(xiàn)基于控制臺的電子時鐘

    C語言實現(xiàn)基于控制臺的電子時鐘

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)基于控制臺的電子時鐘,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言修煉之路靈根孕育源流出?初識C言大道生下篇

    C語言修煉之路靈根孕育源流出?初識C言大道生下篇

    C語言是一門面向過程、抽象化的通用程序設(shè)計語言,廣泛應(yīng)用于底層開發(fā)。C語言能以簡易的方式編譯、處理低級存儲器。C語言是僅產(chǎn)生少量的機器語言以及不需要任何運行環(huán)境支持便能運行的高效率程序設(shè)計語言
    2022-03-03
  • 解決Visual?Studio?Code錯誤Cannot?build?and?debug?because?the

    解決Visual?Studio?Code錯誤Cannot?build?and?debug?because?

    這篇文章主要為大家介紹了解決Visual?Studio?Code錯誤Cannot?build?and?debug?because?the及分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • C語言中strcpy()函數(shù)的具體實現(xiàn)及注意事項

    C語言中strcpy()函數(shù)的具體實現(xiàn)及注意事項

    C語言庫函數(shù)char *strcpy(char *dest, const char *src)把src所指向的字符串復(fù)制到dest,下面這篇文章主要給大家介紹了關(guān)于C語言中strcpy()函數(shù)的具體實現(xiàn)及注意事項的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • C++ vector在多線程操作中出現(xiàn)內(nèi)存錯誤問題及解決

    C++ vector在多線程操作中出現(xiàn)內(nèi)存錯誤問題及解決

    這篇文章主要介紹了C++ vector在多線程操作中出現(xiàn)內(nèi)存錯誤問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • c++中的volatile和variant關(guān)鍵字詳解

    c++中的volatile和variant關(guān)鍵字詳解

    大家好,本篇文章主要講的是c++中的volatile和variant關(guān)鍵字詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C++多線程實現(xiàn)電子詞典

    C++多線程實現(xiàn)電子詞典

    這篇文章主要為大家詳細介紹了C++多線程實現(xiàn)電子詞典,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • c/c++語言位域注意事項分析

    c/c++語言位域注意事項分析

    所謂“位域”是把一個字節(jié)中的二進位劃分為幾個不同的區(qū)域, 并說明每個區(qū)域的位數(shù)。每個域有一個域名,答應(yīng)在程序中按域名進行操作
    2013-09-09

最新評論