スタック領域とは?C言語のStackの仕組みとヒープとの違いを解説

C言語のプログラムでは、メモリは複数の領域に分かれて管理されています。

例えば次のような領域があります。

  • text領域:プログラムのコード
  • data領域:初期値ありのグローバル変数
  • bss領域:初期値なしのグローバル変数
  • heap領域:mallocで使用する動的メモリ
  • stack領域:関数呼び出しで使用するメモリ

この中でも **プログラムの実行に強く関わるのが「スタック領域」**です。

この記事では

  • スタック領域の役割
  • スタックの仕組み
  • ヒープとの違い

実務の視点も交えて解説します。

スタック領域を含むメモリ領域の全体像についてはこちらの記事で解説しています。


メモリ領域解説シリーズ

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

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

目次

スタック領域とは

新人さん

スタック領域って、メモリ構造の図ではよく見るんですが…
実際には何を保存しているんですか?

エンジニアくん

主に関数の実行に必要な情報を保存しているんだ。
ローカル変数や戻りアドレスなどがスタックに積まれるよ。


**スタック領域(Stack)**とは、
関数呼び出し時に使用されるメモリ領域です。

C言語では関数呼び出しのたびに、スタック上に**スタックフレーム(Stack Frame)**と呼ばれる領域が作られます。

このスタックフレームには次のような情報が保存されます。

  • ローカル変数
  • 関数の引数
  • 戻りアドレス
  • 保存されたレジスタ

関数が呼び出されると、
これらの情報が スタックに積まれる(push) 仕組みになっています。

そして関数が終了すると、
そのデータは スタックから取り出され(pop)、メモリが解放されます。

スタックフレームについてはこちらの記事で解説しています。


ローカル変数はどこに保存される?

通常、ローカル変数はスタック領域に保存されます。

例えば関数呼び出し時に、スタックに変数用メモリ確保が行われます。

関数終了時には、その領域が解放されます。

ローカル変数についてはこちらの記事で解説しています。

スタックの特徴

スタック領域には次の特徴があります。

LIFO構造(後入れ先出し)

スタックは LIFO(Last In First Out) の構造を持っています。

つまり

  • 最後に積まれたデータ
  • 最初に取り出される

という仕組みです。

例えば次のような関数呼び出しがあるとします。

main()
 └ funcA()
     └ funcB()

この場合、スタックには次の順でデータが積まれます。

funcB
funcA
main

そして関数終了時は 逆順で戻ります。


自動管理される

スタックのメモリは プログラムが自動で管理します。

つまり

  • malloc
  • free

のような 手動メモリ管理は不要です。

関数が終了すると、そのスタックフレームは自動的に解放されます。

このため、スタックは 高速にメモリ管理できるという特徴があります。


スタックとヒープの違い

初心者さん

スタックとヒープって、どっちもメモリですよね?
何が違うんですか?

エンジニアくん

一番大きい違いは、メモリ管理の方法だね。


スタックとヒープの主な違いは次の通りです。

項目スタックヒープ
用途関数実行動的メモリ
管理方法自動管理プログラマ管理
速度高速比較的遅い
サイズ小さい大きい

ヒープ領域は、主に mallocなどの関数で動的にメモリを確保するために使用されます。

一方で組み込み開発ではヒープ領域の使用にも注意が必要です。

詳しくはこちらの記事で解説しています。


スタックオーバーフローとは

スタック領域には サイズの上限があります。

そのため、スタックを使いすぎると
スタックオーバーフローが発生することがあります。

代表的な原因は次の通りです。

  • 深い再帰呼び出し
  • 大きすぎるローカル配列

例えば次のコードです。

void func() {
    int buffer[100000];
}

このように 大きな配列をローカル変数として確保すると
スタックを圧迫する可能性があります。

その場合は

  • ヒープを使用する
  • 配列サイズを見直す

などの対策が必要です。

スタックオーバーフローについてはこちらの記事で解説しています。


メモリ構造の中でのスタック

C言語のプログラムでは、メモリは一般的に次のような構造になっています。

FlashとRAMの分離、およびHeapとStackの衝突関係

スタックは 高アドレス側から上方向に伸びることが多く、
ヒープは 低アドレス側から下方向に伸びる構造になっています。


割り込みでもスタック領域は使われる

スタック領域は、
関数呼び出しだけで使われるわけではありません。

組み込み開発では、
割り込み(Interrupt)発生時にも、
CPU状態の退避にスタックが使われます。

例えば:

  • プログラムカウンタ(PC)
  • レジスタ
  • ステータスレジスタ

などがスタックへ保存されます。

そのため、

  • 割り込みネスト
  • 深い関数呼び出し
  • スタック不足

などは、重大な不具合につながることがあります。

割り込み処理については、
こちらの記事で詳しく解説しています。

まとめ

スタック領域は、関数の実行に必要な情報を保存する重要なメモリ領域です。

ポイントをまとめます。

  • スタックは関数呼び出しで使用される
  • ローカル変数や戻りアドレスが保存される
  • LIFO構造を持つ
  • メモリは自動管理される
  • ヒープとは用途と管理方法が異なる

C言語のメモリ構造を理解する上で、
スタック領域とヒープ領域の違いは非常に重要なポイントです。

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

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

またスタック領域の配置にかかわるC言語の文法についても当サイトでは解説しています。

エンジニアとして技術を学ぶことは重要ですが、
キャリアや副業についても同時に考える必要があります。

副業の現実や市場価値、今後のキャリア戦略については、
こちらの記事でまとめています。

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

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

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

この記事を書いた人

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

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

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

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

コメント

コメントする


目次