文系未経験から一人前のプログラマーになるまでの日記

文系未経験でプログラマーとして採用してもらえたものの、プログラミング業務ができずに伸び悩んでいるプログラマーが会社で役に立てるようになるまでの日記です。

構造体で最後に配列を作る理由は?(学習中)

【学習の背景】
業務中にコードリーディングしていた時、構造体の最後にReserved[]配列があり、何のために使っているか気になったので、調べることにした。

【仮説】
・後で追加するメンバや、既存の配列の要素数を増やすとき、この配列があると便利なことがある??
→ あると便利なこととは?:
・この配列がある構造体の中に動的にメモリを確保する配列があった場合、
その配列の要素数を大幅に増やしたいが、設計時にあらかじめ決めていた確保するメモリ量をオーバーしてしまうので、
その構造体の配列(メンバ)の次に来るメンバのメモリを壊してしまい...わからん!!

結論:構造体の配列が最後にある理由は何かの理由でメンバ配列の要素数を増やしたいか、新たにメンバを追加したいとき、

この変更をする前にこの構造体を使っていた処理に追加でメモリを確保する領域を増やしてしまうので、
増えた分のメモリ領域が他の処理で使っていたメモリ領域を確保して

→ うーん。わからんけど、たぶんメモリ破壊が起きるからとかだったと思う。
理由:これが説明できないので、わからん...
まあ、メモリ破壊が起きるときの具体的な例をいくつか理解できれば、メモリ破壊が理由で
静的に構造体のメモリ領域を確保する場合は拡張も考えて余分にメモリを確保する目的で配列を構造体の最後に
作ると言える...?

固定でメモリを確保する理由は何??

メモリ破壊でないその他の理由の可能性もある。

メモリ破壊については理解が浅いので、今回の構造体の配列が最後にある理由とは関係ないかもしれないが、
今後必要な知識になる可能性があるので、調べてみる。

スタックについて新たにわかったこと:
・SP(スタックポイント)レジスタとFP(フレームポイント)レジスタを使って関数のジャンプ処理をしている。
具体的には、ある関数Aの中でSPレジスタに変数等の処理を積んでいき(push)、ある関数Bにジャンプするときに、
戻ってくるときの、関数Bのすぐ下の行のアドレスRetBをSPレジスタにpushする。
そして、現在のFPレジスタの中の処理数(変数等の数)をSPレジスタにpushして、
SPレジスタのすべての中身をFPレジスタにコピーする。

関数Bの中でも関数Aの中と同様に変数等の処理を積んでいき(push)、
処理を終える度にSPレジスタの処理をpopしていく。
コピー前のFPレジスタの処理数がpopされたとき、
その値をFPレジスタに代入して、FPレジスタの処理数を関数B処理前に戻して、
FPレジスタを、コピー前の状態に戻す。
次にpopされる処理はRetBなので、これでようやく関数Bを抜けた行へ行ける。

その他ポイント:
・SPレジスタに積まれていくものはauto変数。ただし実際には関数の引数も積まれる。

参考:
www.uquest.co.jp
参考先で分からなかった単語:
・auto変数:ローカル変数のこと。

スタックメモリに関する注意点:

参考:
www.uquest.co.jp

参考先で分からなかった単語:
・スタックオーバーフロー:あるタスクぶんのスタック領域に確保されているメモリ領域を超えてSPレジスタにauto変数を積んでしまってメモリ破壊をしてしまい、結果として、システムが正常に動作しなかったり、最悪の場合はシステムがハングアップしてしまうこと。
・ハングアップ:パソコンやプログラムが力尽きること。
→ この状態になると、パソコンなら再起動、プログラムなら強制終了しないともう一度動かない。

+α:
構造体のインスタンスを2つ作って片方をもう片方に代入し、そのインスタンスがあるブロックを抜けた場合、
代入された方のインスタンスのもともとのアドレスが指すメモリ領域は半永久的に確保され、
代入した方のインスタンスのメモリ領域は2度解放される。
参考:http://www.usamimi.info/~shiva/programs/cfx/cfx_tec_struct_pointer.html