C++: メモリの分散と管理方法、および基礎となる実装の比較

この記事では、主に C および C++ でのメモリ分散と管理方法、および動的メモリ管理に関連するいくつかの関数について説明します。

C および C++ のメモリ分散

次の図は、メモリの分布を非常によく分割したものであり、フォローアップでより詳細な調査が行われる予定ですが、ここでは主に表面的に一般的なものをいくつか調査します。

  • グローバル変数は静的領域で動作します
  • 一時変数はヒープに作用します
  • 動的メモリアプリケーション用のスペースはヒープ上に割り当てられます
  • 一部の定数はコードセグメントに保存されます
    ここに画像の説明を挿入

C++のメモリ管理方法

まずはこのシーンを見てください。

ここに画像の説明を挿入
これは C++ で書かれた非常に一般的なスタックです。main 関数でオブジェクトが定義され、デフォルトでコンストラクターが実行され、クラスのメンバーが初期化されますが、これはスタック領域に生成されます。スタック?

ここに画像の説明を挿入

このとき問題が発生します、malloc で生成されたオブジェクトは内部で初期化されておらず、格納されている値はすべてランダムな値であり、将来使用することはできず、コンストラクターを直接呼び出すことはできません (これから説明します)それについては後で話します)では、これはなぜでしょうか?

その理由は、malloc はこのオブジェクトを生成するだけで、このオブジェクトを初期化しないためです。同様に、free は生成されたオブジェクトを解放するだけで、オブジェクトのデストラクターを呼び出しません。作成されたオブジェクトがヒープ上にない場合はオープンしても問題ありませんスペースを解放しないと、メモリ リークが発生します。具体的な原理は次の図で表すことができます。

ここに画像の説明を挿入
そこで、ここで new を紹介します new の役割はクラス内のメンバ変数の初期化を行うことです 簡単に言うと、new は malloc に基づいてクラス内のコンストラクタを呼び出して初期値を代入するものと理解できますまたは初期化された操作

ここに画像の説明を挿入
new と delete の使用法には主に次のようなものがあります。

int main()
{
    
    
	int* ptr1 = new int;       // 动态申请一个int类型的空间
	int* ptr2 = new int(10);   // 动态申请一个int类型的空间再初始化为10
	int* ptr3 = new int[3];    // 动态申请三个int类型的空间

	delete ptr1;
	delete ptr2;
	delete[] ptr3;
	return 0;
}

演算子 new 関数と演算子削除関数

new および delete は、ユーザーが動的メモリを適用および解放するための演算子です。operator new および Operator delete は、システムによって提供されるグローバル関数です。new は、スペースを適用するために最下層で Operator new グローバル関数を呼び出し、delete は、operator delete global を使用します。最下層で空間を解放する機能

実際、演算子 new は、実際には malloc を通じてスペースを申請します。malloc がスペースの申請に成功した場合は、直接戻ります。そうでない場合は、スペース不足に対してユーザーが提供した対策を実行します。ユーザーがこの措置を提供すると、引き続き実行されます。適用しない場合は例外がスローされます。Operator delete は最終的に free を通じてスペースを解放します。

カスタム型の場合、 new の動作原理は、最初に演算子 new を呼び出し、基礎となるロジック実装として malloc を使用してメモリ空間を作成し、次にコンストラクターを呼び出してオブジェクトを初期化することであることがわかります。 :

ここに画像の説明を挿入

演算子 new 関数は、作成失敗の状況を改善するために malloc に基づいており、コンストラクターと結合されて、最終的に演算子 new にカプセル化されます。

ここに画像の説明を挿入

malloc/free と new/delete の違いは何ですか?

(使用法が簡素化され、動的に適用されるカスタム オブジェクトの初期化問題が解決されます)

  • 簡素化された使用法の観点から:
  1. malloc と free は関数、new と delete は演算子です
  2. malloc によって要求されたスペースは初期化されませんが、new によって要求されたスペースは初期化できます。
  3. malloc はサイズを計算してスペースに適用するパラメーターを渡す必要がありますが、new はスペースのタイプを追加するだけでよく、複数のオブジェクトを作成する場合は [] 内のオブジェクトの数を追加するだけで済みます。
  4. malloc の戻り値は void* で、使用時にキャストする必要があります。New には必要ありません。その後にスペースの型が続きます。
  5. Malloc はスペースの適用に失敗するため、手動でチェックする必要があります。New は例外をキャッチするだけで済みます。
  • 動的に適用されるカスタム オブジェクトの初期化問題を解決するという観点からは、次のようになります。
  1. カスタム タイプのオブジェクトを適用する場合、malloc と free はスペースを開くだけで、コンストラクターとデストラクターを呼び出しません。一方、new はスペースの適用後にオブジェクトの初期化を完了するためにコンストラクターを呼び出し、delete は完了するためにデストラクターを呼び出します。スペースを解放する前のスペース 内のリソースのクリーンアップ
  2. 最下層の観点から見ると、new と delete は最下層で演算子 new と演算子 delete を呼び出し、コンストラクターとデストラクターの呼び出しを追加したり例外をスローしたりして、new と delete をカプセル化するなど、ある程度の変更を実行します。ただし、本質的には、malloc と free は引き続き実行されます

メモリリークの問題

メモリリークとは何ですか? メモリリークの危険性?

メモリ リークとは: メモリ リークとは、プログラムが過失やエラーにより使用されなくなったメモリを解放できない状況を指します。メモリ リークとは、メモリの物理的な消失を指すのではなく、アプリケーションがメモリの特定のセグメントを割り当てた後の設計エラーにより、メモリの特定のセグメントに対する制御が失われ、メモリが無駄に消費されることを指します。
メモリ リークの危険性: メモリ リークは、オペレーティング システムやバックグラウンド サービスなど、大きな影響を与える長時間実行プログラムで発生します。メモリ リークにより、応答がますます遅くなり、最終的にはフリーズします。

おすすめ

転載: blog.csdn.net/qq_73899585/article/details/132032837