質問: 3; ``` lldbでメモリを見てみると、確かにx,y,zは上にむかって積まれていましたが、0xcafecafe+1は配列の`0x7ffeefbff880: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07`より上に積まれています。 これはなぜですか? ``` (lldb) x/128xb &z 0x7ffeefbff840: 0x03 0xf8 0xbf 0xef 0xfe 0x7f 0x00 0x00 0x7ffeefbff848: 0xa0 0xf8 0xbf 0xef 0xfe 0x7f 0x00 0x00 0x7ffeefbff850: 0x02 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x7ffeefbff858: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x7ffeefbff860: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x7ffeefbff868: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x7ffeefbff870: 0xff 0xca 0xfe 0xca 0x00 0x00 0x00 0x00 0x7ffeefbff878: 0x00 0x00 0xff 0xff 0x00 0x00 0x00 0x00 0x7ffeefbff880: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x7ffeefbff888: 0xc8 0x00 0x9a 0x1c 0xb6 0x13 0x7a 0x6c 0x7ffeefbff890: 0xa8 0xf8 0xbf 0xef 0xfe 0x7f 0x00 0x00 0x7ffeefbff898: 0xe5 0x82 0xec 0x69 0xff 0x7f 0x00 0x00 0x7ffeefbff8a0: 0xe5 0x82 0xec 0x69 0xff 0x7f 0x00 0x00 0x7ffeefbff8a8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x7ffeefbff8b0: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x7ffeefbff8b8: 0x78 0xfa 0xbf 0xef 0xfe 0x7f 0x00 0x00 ```
回答: 関数内の自動変数の配置順番なんかは、コンパイラの自由裁量の範囲で、どうにでも変わるものでしょう。 例えばこんな記事があります。 第八回-03 メインメモリとアドレス > > いずれにせよ、変数をメモリ上にどう配置するかはコンパイラの仕事なので、任せておけば問題はない。 > > しかし、変数 (今回学んだのは自動変数と呼ばれるもの) がメモリに配置されるイメージを掴むことは大変重要である。 > > > 続きでこれとか。 第九回-01 スタック領域上での配列の配置 第九回-02 関数内の変数のメモリ配置 こちらはスタック内とは書いていないので固定のデータ領域かもしれませんが。 変数がメモリ上でどのように配置されているかメモ デバッグ版かリリース版か、最適化の有無および最適化もサイズ優先か速度優先か、など様々な条件により変数のレイアウトは変わるでしょう。 **「スタックが低いアドレスに向かって積まれることを学びました。」** に関しては、こちらの概念の方が相応しいですね。 C言語 スタックメモリ【ローカル変数が確保される仕組みを解説】 説明の主題とは微妙に違いますが、関数の中から更に関数を呼び出していくと、スタックの低いアドレスに向かって消費量が伸びていきます。 ただし、関数を呼び出すときのパラメータの積み方は、OSのAPIの呼び出しとか、プログラミング言語を混合して使う等のために決まっています。 それでも、いくつかのパターンがあって、どれが使われているか、どれを使うかは、選択する必要があります。