【図解】C言語のメモリ領域を徹底解説|text/data/bss/heap/stackと設計の関係

目次

C言語のメモリ全体像

一般的なプロセスのメモリ構造は次のようになります。

組み込み開発やC言語において、
メモリ構造の理解は“必須スキル”です。

ただし多くの場合、

  • グローバル変数はdata?
  • 初期化なしはbss?
  • mallocはheap?

という「用語暗記」で止まってしまいます。

しかし本当に重要なのは、

👉 それが設計にどう影響するか

です。

この記事では、Cプログラムのメモリ領域を、構造と実務の両面から整理します。
text/data/bss/heap/stackがそれぞれ何を表し、組み込み開発の設計にどう影響するのかを順番に見ていきます。


メモリ領域解説シリーズ

本記事は「メモリ領域解説」シリーズの1つです。

メモリ領域解説シリーズの全体像はこちら


テキスト領域(コード領域)

ここには実行される命令そのものが入ります。

  • 関数の中身
  • 実行命令
  • constな定数(※環境による)

組み込みでは、ほとんどの場合**フラッシュメモリ(Flash)**に配置されます。

つまり:

  • 実行はできる
  • 書き換えはできない(通常)

という特徴があります。

なぜ重要か?

テキスト領域が増えるということは、
プログラムサイズが増えるということです。

フラッシュ容量が小さいマイコンでは、これも制約になります。


テキスト領域(ROM/FLASH)についてはこちらの記事で解説しています。

データ領域(初期化済みグローバル変数)

ここには、

  • 初期値が与えられているグローバル変数
  • static変数(初期値あり)

が入ります。

例:

int count = 10;
static int mode = 1;

重要なのはここです。

👉 初期値も含めてスタートアップコードでRAMに展開される

組み込みでは:

  • フラッシュに初期値を保持
  • 起動時にRAMへコピー

という動きをします。

つまり、データ領域が大きいと:

  • 起動時間が伸びる
  • RAMを消費する

という影響があります。


初期値のRAMへのコピー(スタートアップコード)の詳細についてはこちらの記事で解説しています。

BSS領域(未初期化グローバル変数)

ここは初心者が一番あいまいな部分です。

例:

int buffer[1000];

初期値を書いていないグローバル変数は、
ビーエスエス(BSS)領域に入ります。

BSSの特徴

  • 実行開始時にゼロクリアされる
  • 実行ファイルに実データを持たない
  • RAMのみ消費する

なぜゼロになるのか?

C言語仕様で「静的記憶域の変数はゼロ初期化」と決まっているからです。

組み込みでの怖さ

巨大配列をここに置くと、

👉 一瞬でRAMが足りなくなる

マップファイルを見たらBSSがほぼRAMを埋めていた、
というのはあるあるです。


データ領域とBSS領域についてはこちらの記事で解説しています。

ヒープ領域(動的確保エリア)

mallocで確保するのがヒープです。

特徴:

  • 実行中にサイズが変わる
  • freeしないと解放されない
  • フラグメンテーション(断片化)が起こる

組み込みで嫌われる理由はここ。

  • 予測不能
  • 断片化する
  • メモリリークが致命傷

リアルタイム性が重要な環境では、
ヒープを使わない設計も多いです。

組み込み開発でmallocが嫌われる理由については、こちらの記事でも解説しています。


スタック領域(関数呼び出しエリア)

関数が呼ばれるたびに使われるのがスタック。

ここに置かれるのは:

  • ローカル変数
  • 引数
  • 戻りアドレス

スタックは上から下へ伸びるのが一般的です。

危険ポイント

  • 再帰
  • 巨大ローカル配列
  • 深い関数ネスト

これらはスタックオーバーフローを引き起こします。

組み込みでは、
スタックサイズをリンカ設定で固定します。

つまり:

👉 設計ミス=即ハング

です。


スタック領域についてはこちらの記事で解説しています。

RAMとFlashの整理

組み込みでは:

領域配置
テキストFlash
データRAM
BSSRAM
スタックRAM
ヒープRAM

つまり本当に怖いのはRAM不足です。

マイコンはFlashよりRAMの方が圧倒的に小さい。

だからメモリ設計が重要になります。

マップファイルの見方

ビルドすると生成される .map ファイル。

例えばこんな記述があります:

Memory ConfigurationName            Origin             Length
FLASH                               0x08000000         512K
RAM                                 0x20000000         128K

そして下の方に:

.bss      0x20000000      0x00004000
.data     0x20004000      0x00001000

ここで見るべきは:

  • BSSサイズ
  • dataサイズ
  • 合計RAM使用量
  • stack確保サイズ

さらには、

  • 最大スタック使用量
  • RAMの残り容量

を確認することが、安全設計に直結します。


メモリマップについてはこちらの記事で解説しています。


実際にRAMが足りなくなるとどうなるか

RAM不足は、必ずしもビルドエラーにはなりません。

  • 起動時にハングする
  • 特定条件でのみ不安定になる
  • まれに再現する不具合が発生する

こうした症状は、メモリ破壊やスタックオーバーフローが原因であることが多いです。

そのため、設計段階で

  • どの領域がRAMを消費しているか
  • 最大使用量はいくつか
  • 安全マージンは確保されているか

を確認することが不可欠になります。


なぜこの理解が設計力につながるのか

前回の記事で触れた通り、

「どこに何が置かれるか」を知らずに設計すると、

  • なんとなくグローバル変数を増やす
  • なんとなくmallocを使う
  • スタックサイズを考えない

というコードになります。

でも、メモリ領域を理解していると、

  • この配列はスタックに置くと危険
  • これはBSSでRAMを圧迫する
  • 初期化コストが起動時間に影響する

と判断できる。

これが設計力です。


よくある設計ミス

特にこのあたりは気をつけてソフトウェア設計をする必要があります。

  • ローカルに巨大配列 → スタック死
  • BSSに巨大バッファ → RAM死
  • malloc多用 → 不安定化

まとめ

メモリ領域は「試験対策の暗記項目」ではありません。

  • text(テキスト)
  • data(データ)
  • bss(ビーエスエス)
  • heap(ヒープ)
  • stack(スタック)

それぞれの役割と制約を理解することが、

組み込みエンジニアとしての土台になります。

C言語学習におすすめの書籍

新・明解C言語 入門編

text/data/bss/heap/stackといったメモリ領域を理解するには、
まずC言語の変数やポインタの基礎理解が重要です。

この書籍は、

  • 配列
  • ポインタ
  • static変数
  • 文字列
  • 関数

などを図やサンプルコードを使いながら丁寧に学べます。

「変数がどこに置かれるのか」
「なぜメモリ領域が分かれているのか」

を理解する土台を作りたい方におすすめの1冊です。

この記事が参考になった方へ

メモリ領域については他の記事でも解説しています。

また、static、const、ポインタ、mallocなど、メモリ領域の理解に関わるC言語文法についても当サイトで解説しています。

技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。

小さなご相談からでもお気軽にご連絡ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

組み込みソフトエンジニアとして働きながら、
C言語・メモリ・ポインタなどの基礎から実務まで解説しています。

副業・キャリアについても実体験ベースで発信中です。

X・Qiita・noteでも発信しています。
X:更新情報・日常
Qiita:技術発信
note:キャリア・副業

▼まずはここから読むのがおすすめ
C言語文法シリーズ
メモリ領域解説シリーズ
割り込み処理解説シリーズ
ソフトウェア設計解説シリーズ
キャリアと副業ロードマップ

コメント

コメントする


目次