首頁  >  文章  >  後端開發  >  C 中的記憶體佈局

C 中的記憶體佈局

WBOY
WBOY原創
2024-07-23 17:25:451178瀏覽

介紹

記憶體佈局是指電腦記憶體的組織和結構方式。它定義了各種系統元件如何劃分和使用記憶體。

這在 C 中至關重要,因為它直接影響變數、函數和資料結構在執行期間的儲存和存取方式。

在本文中,我們將了解 C 中記憶體佈局的基本面向。

C 記憶體佈局中的段

C中的記憶體佈局由不同的段組成,下面是段;

  1. 文字(代碼)段。
  2. 資料段。
  3. 堆。
  4. 堆疊。

下圖描述了 C 的記憶體佈局。

Diagram of C’s memory layout.
現在讓我們詳細討論這些片段。

文字(代碼)段

文字段是 C 程式中儲存編譯後的機器碼指令的記憶體區域。這些指令構成了程式的可執行邏輯,並負責定義其行為。

以下是一個簡單的例子來說明 C 程式中文字段的概念:

#include <stdio.h>

int main() {
    int x = 5;
    int y = 10;
    int sum;

    sum = x + y;
    printf("The sum of %d and %d is %d\n", x, y, sum);

    return 0;
}

編譯器在編譯程式時將原始碼轉換為機器碼。此機器代碼構成了程式的邏輯和行為,並儲存在文字段中。

雖然我們無法直接看到機器碼。我們可以理解,文本段包含了編譯後的指令。

本質上,文字段包含定義程式執行時如何行為的指令。

數據段

資料段分為兩部分:

  • 初始化資料段
  • 未初始化的資料段

初始化資料段

初始化資料段由預先初始化的全域變數、外部變數、靜態變數(局部變數和全域變數)和常數全域變數組成。初始化的資料段有兩個部分,只讀讀寫部分。

具有可以修改的預定義值的變量,即初始化的全域變數、外部變數和靜態(本地和全域)變數儲存在讀寫部分。另一方面,常數變數位於 只讀 部分。

這是一個範例,說明了儲存在初始化資料段中的變量,包括讀寫部分和唯讀部分:

#include <stdio.h>

// Global variable (read-write section)
int globalVar = 10;

// External variable declaration (read-write section)
extern int externVar;

// Static global variable (read-write section)
static int staticGlobalVar = 20;

// Constant global variable (read-only section)
const int constGlobalVar = 30;

int main() {
    globalVar += 5;
    staticGlobalVar += 10;

    printf("Global variable: %d\n", globalVar);
    printf("Extern variable: %d\n", externVar);  // Assuming externVar is defined in another file
    printf("Static global variable: %d\n", staticGlobalVar);
    printf("Constant global variable: %d\n", constGlobalVar);

    return 0;
}

這說明了儲存在初始化資料段的讀寫和唯讀部分中的變數。

未初始化的資料段

未初始化的資料段也稱為BSS(由符號開始的區塊)段由未初始化的全域變數、外部變數和靜態(本地和全域)變數組成。

這些變數在程式執行之前預設初始化為零。他們具有讀寫權限。從而允許在程式執行期間​​讀取和寫入它們。

範例:

#include <stdio.h>

// Uninitialized global variable (goes to the BSS segment)
int globalVar;

// Uninitialized static global variable (also goes to the BSS segment)
static int staticGlobalVar;

int main() {
    // Uninitialized local static variable (goes to the BSS segment)
    static int staticLocalVar;

    printf("Uninitialized Global Variable: %d\n", globalVar);
    printf("Uninitialized Static Global Variable: %d\n", staticGlobalVar);
    printf("Uninitialized Static Local Variable: %d\n", staticLocalVar);
    return 0;
}

在此程式中,未初始化的變數預設包含零或空值。這是由於編譯器會自動初始化所造成的。這顯示了儲存在 BSS 段中的變數的行為。

堆疊

堆是運行時用於動態記憶體分配的記憶體區域。這允許在程式執行期間​​根據需要分配和釋放記憶體。 malloc()calloc()realloc()free() 等函數用於記憶體分配和釋放在堆中。程式的所有部分都可以存取堆。

範例:

#include <stdio.h>
#include <stdlib.h>

int main() {
    // Dynamically allocate memory for an integer variable on the heap
    int *ptr = (int *)malloc(sizeof(int));

    return 0;
    }

此程式碼片段示範了 C 語言中動態記憶體分配的簡單用法。它引起人們對請求記憶體、初始化指向該記憶體的指標以及正確管理記憶體以避免洩漏所涉及的步驟的關注。雖然此範例中不包括錯誤處理和記憶體釋放,但這些是實際應用中使用動態記憶體的關鍵組成部分。

堆疊

棧段主要功能是管理函數呼叫和儲存局部變數。這部分在程式的記憶體佈局中至關重要,因為它控製程式內的流程。堆疊採用後進先出(LIFO)結構,這表示最近新增的資料將首先被刪除。這使得堆疊對於管理局部變數和巢狀函數呼叫非常有效。

範例:

#include <stdio.h>

void functionA(int n) {
    int a = n + 1; // Local variable
    printf("In functionA, a = %d\n", a);
}

void functionB() {
    int b = 10; // Local variable
    printf("In functionB, b = %d\n", b);
    functionA(b); // Call to functionA
}

int main() {
    int x = 20; // Local variable
    printf("In main, x = %d\n", x);
    functionB(); // Call to functionB
    return 0;
}

The code explains how stack frames store local variables. New stack frames are created by the function calls and are eliminated when the functions return. The printf instructions facilitate the visualization of each function's local variable values. The execution flow follows the calls to and returns from functions.

Conclusion

C programmers can improve their coding techniques and gain a better understanding of how their programs interact with memory by mastering these concepts. Understanding memory layout is a vital skill in your programming toolbox, whether you're optimizing for performance or troubleshooting a complex problem.

Feel free to follow, comment, and leave claps. Happy Coding!

Let’s connect on LinkedIn.

以上是C 中的記憶體佈局的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn