-4

インタビューでこれらの質問をされました。

  1. バイナリ コードとデータが分離されたのはなぜですか。つまり、なぜデータ セグメントを計画したのでしょうか。

2.

class A
{
private :
    int i;
public:
    void show()
    {
        printf("hello");
    }
};
int main()
{
    A* a = NULL; (what happens in object table?)
        A* aa =  new A();  (what happens in object table?)

        a->show();
    aa->show();

    delete aa;
    return 0;
}

aa と a の正確な違いと、メモリ内でのオブジェクトの正確な動作。

4

3 に答える 3

2

コードセグメントとデータセグメント

コード セグメントは読み取り専用ですが、データ セグメントは読み取り/書き込み可能です。これら 2 つのセクションを混在させると、コードを安全に保ちながらデータを更新することが課題になります。1 つの例は、Lol4t0 が指摘したとおりです。

OS メモリ管理に関しては、コード セグメントはファイル システム上の元の実行可能ファイルにスワップ アウトされますが、データ セグメントは変更されると見なされ、ページング ファイルにスワップ アウトされます。それらを混在させると、実行可能ファイルをページング ファイルとして再利用する利点が失われる可能性があります。

また、コードセグメントは通常、読み取り専用のメモリページにロードされます(VirtualAlloc(PAGE_READONLY) )

a(ヌル) と aa (非ヌル)

a と aa 自体は単に A* 型のスタック変数ですが、a は NULL を指し、aa はヒープに割り当てられたオブジェクトを指します。

a->show() は次のように変換されます。

A_show(a)
//which is:
A_show(NULL)

show() ではメンバー変数が参照されていないため、これは正常に機能するはずです。

aa->show() は次のように変換されます:

A_show(aa)

ここで aa は有効なアドレスなので、show() でメンバー変数を参照しても機能します。

実行時に解決されるため、各オブジェクトに vptr が必要な仮想関数とは異なり、メンバー関数は、最初のパラメーターとしてthisを受け取り、コンパイル時にコンパイラーによって解決される単なる通常の関数であることに注意してください。

于 2012-08-17T17:13:17.420 に答える
1

コードとデータを分離するもう 1 つの理由は、メモリ管理です。

物理メモリが少なくなったら、コード ページを「忘れて」、必要なときにディスクから読み直すことができます。しかし、データに対して同じことを行うことはできません。この状況では、ページをスワップ/ページ ファイルに移動する必要があります。コードとデータページが混在している場合は、それらをスワップ/ページに保持する必要があるため、この戦略によりリソースが節約されます。

まあ、私は完全を装うつもりはありません。

于 2012-08-17T17:44:14.750 に答える
1

2番目の部分はちょっとしたひっかけ問題だと思います。セグメンテーション違反が発生すると思うかもしれA::showませんが、クラスのデータ部分を参照しないため、バイナリ コードの一部になるように最適化され (ほぼ静的メソッドのように)、"hellohello" が返されます。printf を変更するだけprintf("hello %d ", i);で、セグメンテーション違反が発生します。

于 2012-08-17T17:52:17.910 に答える