プログラムで確保されるメモリについて


プログラムで確保されるメモリ領域には、スタック領域とヒープ領域があると思います。

スタック領域は関数内などで定義される変数によって確保される領域で、  
コンパイルをした時点でメモリの大きさが決まり、確保や解放もOS任せになります。

それに対してヒープ領域は動的確保(mallocとかnew)で確保される領域のことで、  
プログラマが解放しない限りそこに残り続けます。

ここで質問なのですが、(上の解釈が間違っている時はご指摘ください)  
例えば以下のコード(C++)があったとします。

[code]

    void Hoge()
    {
        int hoge1 = 0;
    
        for( int i = 0; i < 10; ++i ){
            hoge1+=i;
        }
    }
    
[/code]

ここで変数`hoge1`、for文内の変数`i`はどちらもスタック領域に確保されると思います。

また、変数`i`のスコープはfor文内のみで、ほかからはアクセス出来ません。  
質問というのは、for文を抜けた時点で、変数`i`はメモリ上には残るのでしょうか？

何が知りたいかというと、変数のスコープが小さければ小さいほど、  
メモリの節約になるのかということです。  
よろしくお願いします。




> for文を抜けた時点で、変数iはメモリ上には残るのでしょうか？

ほとんどのケースで残ります。通常スタックの増減は関数に入る時と出る時に実施されます。BLUEPIXY さんのコメントにもあるように、
_スコープに合わせてスタックを増減する_
可能性もゼロではありませんが、スタックの増減は決して安価な操作ではないので、スコープという単位で行うのは現実的ではありません。

> 何が知りたいかというと、変数のスコープが小さければ小さいほど、メモリの節約になるのかということです。

質問の例では節約になりませんが、本質的には節約になる可能性があります。以下の様なコードを考えてみてください。

[code]

    void Foo() {
        int bar = 0;
    
        for (int i = 0; i < 10; ++i) {
            bar += i;
        }
        for (int j = 10; j > 0; --j) {
            bar += j;
        }
    }
    
[/code]

前半のループで使用している `i` と、後半のループで使用している `j` は、スコープが分かれていてお互いに独立しています。このような時、`i` と
`j` へ同じメモリ領域を用いて/再利用して、この関数が使用するスタックメモリの総量を少なくする、コンパイラがそういう最適化を行う余地が生まれます。




> for文を抜けた時点で、変数iはメモリ上には残るのでしょうか？

ほとんどのケースで残ります。通常スタックの増減は関数に入る時と出る時に実施されます。BLUEPIXY さんのコメントにもあるように、
_スコープに合わせてスタックを増減する_
可能性もゼロではありませんが、スタックの増減は決して安価な操作ではないので、スコープという単位で行うのは現実的ではありません。

> 何が知りたいかというと、変数のスコープが小さければ小さいほど、メモリの節約になるのかということです。

質問の例では節約になりませんが、本質的には節約になる可能性があります。以下の様なコードを考えてみてください。

[code]

    void Foo() {
        int bar = 0;
    
        for (int i = 0; i < 10; ++i) {
            bar += i;
        }
        for (int j = 10; j > 0; --j) {
            bar += j;
        }
    }
    
[/code]

前半のループで使用している `i` と、後半のループで使用している `j` は、スコープが分かれていてお互いに独立しています。このような時、`i` と
`j` へ同じメモリ領域を用いて/再利用して、この関数が使用するスタックメモリの総量を少なくする、コンパイラがそういう最適化を行う余地が生まれます。

