スコープ終了後のスタックメモリ使用

スコープ終了後のスタック領域の使用

説明

ローカル変数のブロックスコープが終了した後も、その変数へのポインターや参照を使うと、寿命が終了したオブジェクトにアクセスすることになります。

想定される影響

  • 無効なスタック領域の読み書きにより、誤ったデータ処理やクラッシュが発生するおそれがあります。
  • 同じスタックフレーム内の別の値が破損する可能性があります。

対処方法

  1. ローカル変数のアドレスをブロックの外に保持したり、そこで使ったりしないでください。
  2. より長い寿命が必要なら、呼び出し元が所有するバッファーや、所有権が明確な動的確保オブジェクトを使用してください。
  3. C++では、所有権と寿命を安全に表せる型を優先してください。

例

変更前

c
void run(void) {
    int *p;
    {
        int value = 1;
        p = &value;
    }
    *p = 2;
}

変更後

c
void run(void) {
    int value = 1;
    int *p = &value;
    *p = 2;
}

解説:

  • 変更前: 内側のブロックが終わると value は無効になりますが、p を通じて使用されています。
  • 変更後: 対象変数の寿命が続いている間だけポインターを使用しています。

参考資料