記事ディレクトリ
1 はじめに
C 言語を学習するとき、動的メモリ管理、つまり、使用するためにヒープ上の一部のメモリを動的に開くことを学びました。C 言語のメモリ管理の方法は C++ でも使用できますが、まだできないところがいくつかあります。については何もしないので、今日は C++ メモリを管理する方法を学びましょう。
2. C/C++ メモリ分散
メモリ管理を学ぶ前に、まず C/C++ のプログラム メモリ領域が何に分割されているかを理解しましょう。
1. スタックはスタックとも呼ばれ、非静的ローカル変数/関数パラメータ/戻り値などが格納され、下に向かって成長していきます。
2. メモリ マップ セグメントは、共有ダイナミック メモリ バンクをロードするための効率的な I/O マッピング方法です。ユーザーはシステム インターフェイスを使用して、プロセス間通信用の共有共有メモリを作成できます。
3. ヒープはプログラムの実行中に動的メモリ割り当てに使用され、ヒープは増加する可能性があります。
4. データセグメントには、グローバルデータと静的データが格納されます。
5. コードセグメント。実行可能コード/読み取り専用定数を保存します。
3. C言語の動的メモリ管理
C 言語の動的メモリ管理は、malloc、realloc、calloc、free の 4 つの関数に依存します。
これらの関数の具体的な機能については、ブロガーが以前に公開した C 言語の動的メモリ管理の記事に詳細な説明が記載されています。
void Test()
{
int* p1 = (int*)malloc(sizeof(int));
free(p1);
int* p2 = (int*)calloc(4, sizeof(int));
int* p3 = (int*)realloc(p2, sizeof(int) * 10);
//这里不需要free(p2)
free(p3);
}
int main()
{
Test();
return 0;
}
4. C++のメモリ管理方法
C 言語のメモリ管理方法は C++ でも引き続き使用できますが、場所によっては無力であり、使用するのがより面倒であるため、C++ は独自のメモリ管理方法、つまり new 演算子と delete 演算子による動的メモリ管理を提案しました。
ただし、new と delete では組み込み型とカスタム型の処理方法が異なるため、new と delete がそれぞれ組み込み型とカスタム型をどのように処理するかを見てみましょう。
4.1 組み込み型
組み込み型の場合、new/delete と malloc/free の間に本質的な違いはなく、使用法の違いのみであり、new/delete の使用法は簡略化されています。
以下では、組み込み型の new と delete の使用法を直接説明します。
void Test()
{
//C语言
//动态申请一个int类型的空间
int* p1 = (int*)malloc(sizeof(int));
//C++
//动态申请一个int类型的空间
int* p2 = new int;
//申请5个int的数组
int* p3 = new int[5];
//申请1个int对象,初始化为5
int* p4 = new int(5);
//C++11支持new[] 用{}初始化 C++98不支持
int* p5 = new int[5]{
1,2,3};
//C语言
free(p1);
//C++
delete p2;
delete[] p3;
delete p4;
delete[] p5;
}
int main()
{
Test();
return 0;
}
注: 単一要素のスペースを適用および解放するには、new 演算子と delete 演算子を使用して連続スペースを適用および解放し、new[] と delete[] を使用します。これらは一致する必要があります。
4.2 カスタムタイプ
カスタム タイプのスペースを適用する場合、new はコンストラクターを呼び出し、delete はデストラクターを呼び出しますが、malloc と free は呼び出しません。
例えば:
class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
//C语言
//malloc
//在堆上申请空间
A* p1 = (A*)malloc(sizeof(A));
if (p1 == NULL)
{
perror("malloc fail\n");
return 0;
}
//释放空间
free(p1);
//C++
//new
//在堆上申请空间、调用构造函数初始化
//A* p2 = new A;
A* p3 = new A(10);
//调用析构函数清理对象中的资源、释放空间
delete p3;
return 0;
}
概要: new/delete と malloc/free の最大の違いは、new/delete はカスタム型用のスペースを開くだけでなく、組み込み型の場合とほぼ同じであるコンストラクターとデストラクターも呼び出すことです。
5. 演算子新規および演算子削除関数
new と delete は、ユーザーが動的メモリを適用および解放するための演算子です。
Operator new および Operator delete は、システムによって提供されるグローバル関数です。
New は最下層で演算子 new グローバル関数を呼び出してスペースを適用し、delete は最下層で演算子 delete グローバル関数を使用してスペースを解放します。
演算子 new:
この関数は実際に malloc を使用して領域を申請します。malloc が領域の申請に成功するとそのまま戻ります。領域の申請に失敗した場合は、領域不足の対策を試みます。異常です。
演算子削除:
この関数は最終的に解放を通じてスペースを解放します。
6. 新規・削除の実施原則
組み込みタイプ:
組み込みタイプのスペースを申請する場合、new と malloc、delete、free は基本的に似ています。
違いは、
new/delete は単一要素のスペースに適用および解放され、new[] と delete[] は連続スペースに適用および解放され、new はアプリケーション スペースが失敗したときに例外をスローし、malloc は NULL を返します。
カスタムタイプ:
新しい原理:
1. 演算子 new 関数を呼び出してスペースを適用します。
2. 適用されたスペースでコンストラクターを実行して、オブジェクトの構築を完了します。
削除の原則:
1. スペースに対してデストラクターを実行して、オブジェクト内のリソースのクリーンアップを完了します。
2. オペレーターの削除関数を呼び出して、オブジェクトのスペースを解放します。
新しいT[N]の原理:
1. 演算子 new[] 関数を呼び出し、実際に演算子 new[] 内の演算子 new 関数を呼び出して、N 個のオブジェクト空間の適用を完了します。
2. 適用された空間に対してコンストラクターを N 回実行します。
削除の原則[]:
1. 解放されたオブジェクト空間で N 回デストラクターを実行し、N オブジェクト内のリソースのクリーンアップを完了します。
2. 演算子 delete[] を呼び出して領域を解放し、実際に演算子 delete[] 内の演算子 delete 関数を呼び出して領域を解放します。
7. 新しい式を配置します (placement-new)
新しい式を配置するには、コンストラクターを呼び出して、割り当てられた元のメモリ領域内のオブジェクトを初期化します。
使用形式:
new (place_address) タイプまたは new (place_address) type(initializer - list)
place_address はポインターである必要があり、initializer - list はタイプの初期化リストです
使用シナリオ:
新しい式の位置決めは通常、メモリ プールと組み合わせて使用されます。実際には。メモリプールによって確保されたメモリは初期化されないため、カスタム型のオブジェクトの場合は、newの定義式を使用して明示的にコンストラクタを呼び出して初期化する必要があります。
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
A* p1 = new A;
A* p2 = (A*)malloc(sizeof(A));
if (p2 == nullptr)
{
perror("malloc fail");
return 0;
}
//new(p2)A;
new(p2)A(10);
return 0;
}
8. エンディング
ここでは C++ のメモリ管理の方法を学習しました。new と delete を学習した後、new と delete は malloc や free よりもはるかに単純であるだけでなく、より実用的でインテリジェントであるため、将来的には new と delete を使用してみます。
最後に、辛抱強く読んでサポートしていただいたことに感謝します。この記事がよく書かれていると思う友人は、3 回フォローしてサポートすることができます。この記事に質問がある場合、または間違いがある場合は、私にプライベート メッセージを送信するか、コメント欄にメッセージを残してください。ディスカッション、皆さんに改めて感謝します。