Cygwinのg++で毎回、実行時に変数のアドレスが一緒になるのは何故？


特に困っているわけではないのですが、素朴な疑問として、  
Cygwinのg++で次のコードを実行すると、Cygwinだけが毎回同じアドレスを表示します。  
そもそもOSは仮想アドレッシングをしていて、  
実際の物理アドレスとは違う値を表示しているのは理解していますが、  
Windows(MSVC)/CentOS(g++)/Ubuntu(g++)で下記コードを実行すると  
毎回違うアドレスを表示するのですが、  
Cygwinのg++だけ何度実行しても同じアドレスを表示します。  
どうしてこのような結果になるのかご教示いただけないでしょうか。  
さらに不思議なことにprintf("%p\n", ...)の結果が  
Cygwinでのみ6桁で表示されるのですが(他は8桁、CentOSの64bit版の場合は12桁)、これもなぜなのかわかりません。

[code]

    #include <cstdio>
    
    int main()
    {
        int c = 1;
        int *a;
        int &b = c;
        a = &c;
    
        printf("変数に格納されている値\n");
        printf("a: %d\n", *a);
        printf("b: %d\n", b);
        printf("c: %d\n", c);
        printf("アドレス\n");
        printf("a: %p\n", a);
        printf("b: %p\n", &b);
        printf("c: %p\n", &c);
    
        getchar(); // 一時停止
    
        return 0;
    }
    
[/code]

実行結果例(MSVC)

[code]

    変数に格納されている値
    a: 1
    b: 1
    c: 1
    アドレス
    a: 007EF940
    b: 007EF940
    c: 007EF940
    
[/code]

※アドレスの値の先頭に0xが付くなどはどうもコンパイラ依存のようです。  
プログラム毎に独立したメモリ空間を使うため、毎回アドレスが変わると思っていたのですが、  
Cygwinのみが同じアドレスを指します。

ちなみに、`static int c = 1;`とすればどの環境でも毎回、アドレスは同一になります。  
ひょっとするとこのような質問はstackoverflow的には好ましくないのかもしれません……。

**回答を得た後の追記**  
**_質問する時点では知らなかったのですが、セキュリティ対策がなしの設定ではどのコンパイラ(もっと正確にいうと処理系)も毎回同じアドレスになる、というのが普通です。Cygwin以外が本当は通常と異なる動きをしていました（ASLR等のセキュリティ対策がON）_**  
また、私自身の質問が混乱した記述になっていますが、同じアドレスから通常は始まる理由は[アドレス空間](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E7%A9%BA%E9%96%93)によると、

>
> ユーザ空間または「ユーザー仮想アドレス空間」はユーザープロセスの動作するアドレス空間である。コンピュータシステム上で動作する各プロセスは、それに対応するデータとコードを持ち、実行中にはそれらがユーザ空間上にロードされる。ユーザ空間はプロセス毎に割り当てられ、それぞれのアドレス範囲は同じである。従って、仮想記憶方式のオペレーティングシステムでは、ユーザープログラムのコードやデータは同じアドレスから開始されるようになっていることが多い。

とのことです。




Cygwin については不明ですが、Linux OS で stack pointer や base pointer
の値が実行ごとに変化するのは、ASLR(Address Space Layout Randomization)が有効になっているからだと思います。

# ASLR については調べれば分かることですので、ここでは説明を省きます。

ASLR の設定は変更可能です。

[code]

    $ cat /proc/sys/kernel/randomize_va_space
    2
    
[/code]

デフォルトは有効ですが、"0" を設定すると無効になります。

[code]

    $ sudo bash -c "echo 0 > /proc/sys/kernel/randomize_va_space"
    $ cat /proc/sys/kernel/randomize_va_space
    0
    
    $ ./example
        :
    アドレス
    a: 0xbffff668
    b: 0xbffff668
    c: 0xbffff668
    
    $ ./example
        :
    アドレス
    a: 0xbffff668
    b: 0xbffff668
    c: 0xbffff668
    
[/code]




Cygwin については不明ですが、Linux OS で stack pointer や base pointer
の値が実行ごとに変化するのは、ASLR(Address Space Layout Randomization)が有効になっているからだと思います。

# ASLR については調べれば分かることですので、ここでは説明を省きます。

ASLR の設定は変更可能です。

[code]

    $ cat /proc/sys/kernel/randomize_va_space
    2
    
[/code]

デフォルトは有効ですが、"0" を設定すると無効になります。

[code]

    $ sudo bash -c "echo 0 > /proc/sys/kernel/randomize_va_space"
    $ cat /proc/sys/kernel/randomize_va_space
    0
    
    $ ./example
        :
    アドレス
    a: 0xbffff668
    b: 0xbffff668
    c: 0xbffff668
    
    $ ./example
        :
    アドレス
    a: 0xbffff668
    b: 0xbffff668
    c: 0xbffff668
    
[/code]

