プログラム foo.c を 2 つの異なる端末で実行し、実行中のローカル変数のアドレスを出力した場合。それらは同じでしょう。ただし、たとえばシェル内でフォークして実行するというコンテキストでは、 foo.c などのプログラムを実行します。シェルのまったく同じコピーを作成し、 foo.c を実行します。それらは同じ仮想アドレス空間を持っていますか。また、プログラムが再帰的に自分自身を呼び出した場合、再帰的に呼び出された同じ変数は同じアドレス空間を持ち、このプログラムは独自のアドレス空間内でどのように成長するのでしょうか?
2 に答える
プログラム foo.c を 2 つの異なる端末で実行し、実行中のローカル変数のアドレスを出力した場合。それらは同じでしょう。
必ずしもそうとは限りませんが、最近のオペレーティング システムではアドレス空間レイアウトのランダム化が使用されています。つまり、メモリ アドレスは、実行ごとに変更される可能性があります。
たとえば、シェル内でフォークして実行するコンテキストでは、 foo.c などのプログラムを実行します。シェルのまったく同じコピーを作成し、 foo.c を実行します。それらは同じ仮想アドレス空間を持っていますか。
いいえ、各プロセスには独自の仮想アドレス空間があります。変数のアドレスは同じに見えるかもしれませんが、一方のプロセスでローカル変数に書き込んでも、もう一方のプロセスには影響しません (明示的にメモリを共有していない限り)。
また、プログラムが再帰的に自分自身を呼び出した場合、再帰的に呼び出された同じ変数は同じアドレス空間を持ち、このプログラムは独自のアドレス空間内でどのように成長するのでしょうか?
プロセスとスレッドの違いを調べて、ここで何が起こっているのかをよりよく理解してください。プログラムが forkする場合、子プロセスには別のアドレス空間があります。関数がプログラム内でそれ自体を呼び出す場合、関数は同じアドレス空間で実行されますが、ローカル変数は各スタック フレームで分離されます。グローバル (または静的) 変数は、関数呼び出し間で同じメモリ アドレスになります。
2つの異なる端末でfoo.cを実行し、ローカル変数のアドレスを出力した場合、同じように表示されます。ただし、これらは2つの異なる変数であり、たまたま同じ値を持っています。
それらはメモリ内の同じ領域を指していません。
シェルからフォークすると、プロセスは仮想メモリの2つの異なる領域内に2つの別個の異なる変数を持つようになります。
実際、これはfoo.cからプロセスを生成する場合に当てはまります。
2つのプロセス間でメモリを共有したい場合は、スレッドを生成するか、共有メモリを使用する必要があります。