4

次のような関数があるとします。

MyClass &MyFunction(void)
{
  static MyClass *ptr = 0;
  if (ptr == 0)
    ptr = new MyClass;
  return MyClass;
}

問題はプログラムの終了時です。ptr 変数が無効になることはありますか (つまり、その ptr の内容は終了プロセスによってクリーンアップされます)。この関数が漏れていることは承知していますが、簡単にするための例にすぎません。

同じ質問は、ポインター以外の他のプリミティブにも当てはまります。静的な整数を持っている場合、その整数の値は常に終了まで持続しますか、それとも静的な破棄順序の問題により可変ですか?

編集:

明確にするために、静的ポインター (または int や float などの他のプリミティブ型) の内容が実際にどうなるのかを知りたいのですが、それが指しているメモリではありません。たとえば、ptr が、他の静的クラスのデストラクタでチェックしたいメモリ アドレスを指しているとします。ptr の内容が変更されない (つまり、静的破棄プロセス中にポインター値がクリーンアップされない) という事実を信頼できますか?

ありがとう、ジョー

4

5 に答える 5

6

プロセスが終了すると、それに割り当てられたすべてのメモリ ページが OS によって解放されます (他の誰かが使用しているモジュロ共有メモリ ページ)。

ただし、他の人が指摘するように、 MyClass のデストラクタは呼び出されません。ptr が指す値も変更されません。値が 123 の static int がある場合、その値はプロセスの存続期間の最後まで 123 のままになります。

于 2008-11-20T15:09:43.103 に答える
4

最新のオペレーティング システムでは、アプリケーションのメモリはすべて、そのアプリケーションに固有の「ヒープ」に割り当てられます。アプリケーションが終了すると、そのヒープ内のすべてのメモリが解放されます。

そのため、メモリの割り当ては解除されます、デストラクタ forMyClassが呼び出されることはありません。これは、デストラクタがメモリ以外のリソースの解放を担当している場合に問題になる可能性があります (ファイル システムのロックが一般的な例です)。

于 2008-11-20T15:06:45.043 に答える
3

更新された質問に答えるには、はいと言います。静的破棄プロセス全体で、その静的ポインターの値が残っていることに頼ることができます。それが指しているメモリは解放されている可能性がありますが、別の静的クラスのデストラクタが変更しない限り、ポインタ自体の値は変更されないままにする必要があります。

于 2008-11-20T15:16:07.380 に答える
3

あなたの質問に答えるには:

'imagine that the ptr points to some memory address which I want to check in the destructor of some other static class'

答えはイエスです。
ポインターの値 (アドレス) を確認できます。
ポインターで削除を呼び出していない場合は、コンテンツを見ることができます。

静的関数変数は、作成とは逆の順序でデストラクタが呼び出されるという点で、静的クラス変数およびグローバル変数 (別名非ローカル静的)と同じように動作します。整数、浮動小数点数、ポインタ(POD) にはデストラクタがないため、プロセスが削除されるまで何も起こりません。

POD オブジェクト: データは他のオブジェクトのデストラクタから安全に参照できます (グローバル s も含む)。

その他の静的オブジェクト (つまり、デストラクタを持つもの): 一般的なケースでは、main() が終了した後にこれらのオブジェクトにアクセスするのは安全ではありません。作成の順序は複雑です:構築順序を参照してください)。それは可能ですが、オブジェクトがまだ生きていることを確認するために明示的な予防措置を講じる必要があります。

注: 非ローカル静的:

メモリは常にそこにあり、デストラクタが呼び出された後はオブジェクトが無効になります (POD にはデストラクタがないことに注意してください)。

注: スタック:

それらが宣言されているスコープが終了するまでのみ有効です。
スタックがポップされた後、それが存在するメモリ ページがドロップされる可能性があり、アクセスしようとすると SEG フォールトが発生する可能性があります。

注: ヒープ:

それを割り当てたポインターで delete を呼び出すまで有効です。
ポインタが削除されると、再利用される可能性があるため、値はランダムになる可能性があります。メモリがあったページも削除される可能性があります。ドロップされたページにアクセスすると、SEG 障害が発生します。

于 2008-11-20T16:50:12.730 に答える
1

簡単な答えは「いいえ」です。プログラムの終了時にポインターが「無効になる」ことはありません。つまり、ポインタ値は自動的に null にリセットされず、それが指す MyClass オブジェクトのデストラクタは自動的に呼び出されません。

これは、ポインターが「プリミティブ型」、つまりオブジェクトではないためです。

オブジェクトである非ローカル (つまり、グローバルまたは静的) 変数がある場合、規則は異なります。オブジェクトのデストラクタは、exit() を呼び出すか、メイン関数から戻ることによってプログラムが終了したときに呼び出されます。プログラムが abort() を呼び出して終了した場合は呼び出されません。

于 2008-11-20T15:18:41.293 に答える