目次
1. C/C++ のメモリ分散
1. C/C++におけるプログラムメモリ領域の分割
メモリ内では、OS の管理を容易にするためにいくつかの領域に分割されており、主に次の部分に分かれています。
- カーネル空間 (ユーザーコードは読み書きできません)
- スタック(下方向に成長): スタックとも呼ばれ、非静的ローカル変数、関数パラメータ、戻り値など
- メモリ マッピング セグメント: 共有ダイナミック メモリ ライブラリをロードするために使用される効率的な IO マッピング方法であり、ユーザーはシステム インターフェイスを使用してプロセス間通信用の共有メモリを作成できます。
- ヒープ(上向きに増加):プログラムの実行中に動的メモリ割り当てに使用されます。mallo/realloc... からの値はヒープ上にあります
- データセグメント(静的領域とも呼ばれます):グローバル変数と静的変数を格納します
- コードセグメント(定数領域):実行可能コード/読み取り専用定数を格納
char2はどこですか?スタック上のローカル変数
* char2 はどこですか? 配列の名前は最初の要素のアドレスです。char2 はスタック上のa のアドレスを指します。 *char2 は a を指します。pChar3 は どこにありますか? スタック上のローカル変数* pChar3 は どこにありますか? コードセグメント(定数領域)内の文字定数を指します。ptr1 は どこにありますか? ローカル変数、スタック上* ptr1 は どこにありますか? ヒープ上の mallo からの値を指します
2. C言語による動的メモリ管理
1.malloc/calloc/realloc/free
void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗? 不需要
free(p3 );
}
-
malloc: size バイトのメモリを開きます。割り当てが成功すると、このメモリの開始アドレスが返されます。失敗すると、null ポインタが返されます。返される開始アドレスは void * 型です。
- calloc: num* 型バイトのアドレスを開き、0 に初期化します。 size が 0 の場合、戻り値は特定のライブラリに依存します (null ポインターかどうかは不明) が、返されたポインターは逆参照できません。開発が成功した場合は開始アドレスと型が void* を返し、開発が失敗した場合は null ポインタを返します。
- realloc: ptr が指すメモリ ブロックのサイズを変更します。この関数はメモリ ブロックを新しい場所に移動し、元の 2 つのサイズのうち小さい方を保持します。ptr が null ポインタの場合、関数は malloc と同じです。
3. C++ での動的メモリ管理
1.新規・削除操作内蔵型
void Test()
{
// 动态申请一个int类型的空间
int* ptr4 = new int;
// 动态申请一个int类型的空间并初始化为10
int* ptr5 = new int(10);
// 动态申请10个int类型的空间
int* ptr6 = new int[10];
delete ptr4;
delete ptr5;
delete[] ptr6;
}
単一要素のスペースの適用と解放には new 演算子と delete 演算子を使用し、連続したスペースの適用と解放には new[] と delete[] を使用します。演算子は一致する必要があることに注意してください
2.カスタムタイプの新規および削除操作
class A
{
public:
//构造
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
//注:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与
free不会。
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间
还会调用构造函数和析构函数
A* p1 = (A*)malloc(sizeof(A));
A* p2 = new A(1);
free(p1);
delete p2;
// 内置类型是几乎是一样的
int* p3 = (int*)malloc(sizeof(int)); // C
int* p4 = new int;
free(p3);
delete p4;
A* p5 = (A*)malloc(sizeof(A)*10);
A* p6 = new A[10];
free(p5);
delete[] p6;
return 0;
}
4. 演算子の新規作成および演算子の削除機能
1.演算子新規関数と演算子削除関数
new および delete は、 ユーザーが動的メモリを申請および解放するための 演算子 です。システムによって提供される グローバル関数である new は 、 下部にある演算子 newグローバル関数を呼び出してスペースを適用し、 delete は下部にある演算子 deleteグローバル関数を使用してスペースを解放します。演算子 new は、 実際には mallocを通じて スペースを適用します 。 malloc が スペースの適用に成功すると、直接戻ります。それ以外の場合は、ユーザーが提供したスペース不足への対応策を実装します。ユーザーがこの措置を提供した場合は引き続き適用され、それ以外の場合は適用されます 。例外がスローされます。 delete 演算子は、 最終的に freeを通じて スペースを解放します 。
5. 新規および削除の実装原則
1. 組み込み型
組み込みタイプのスペースを申請している場合、 new と malloc 、 delete と free は基本的に似ています。違いは次のとおりです。new/delete は単一要素のスペースに適用して解放します。new[]とdelete[] は連続スペースに適用します。new はスペースの適用に失敗すると例外をスローし、mallocはNULLを返します。
2.カスタムタイプ
新しい原理
1. 新しいオペレーターに電話してスペースを申請します
2. 要求されたスペースでコンストラクターを実行して、オブジェクトの構築を完了します。
- 削除原則
1. スペースに対してデストラクターを実行して、オブジェクト内のリソースのクリーンアップを完了します。
2. 演算子の削除関数を呼び出して、オブジェクトのスペースを解放します。
- 新しいT[N]の原理
1. 演算子 new[] 関数を呼び出し、 実際に 演算子 new[]内の 演算子 new関数を呼び出して、 Nオブジェクト空間に対するアプリケーションを完了します。2. 要求されたスペースで コンストラクターを N回実行します。
- 削除の原則[]
1. 解放されたオブジェクト空間で N 個の デストラクターを実行して、 N個のオブジェクト 内のリソースのクリーンアップを完了します。2.スペースを解放するには 、operator delete[] を呼び出します 。実際には、operator delete は、スペースを解放するために、operator delete[]内で呼び出されます。スペースを作る
malloc/freeとnew/deleteの違い
malloc/free と new/delete の共通点は、どちらもヒープからスペースを申請し、ユーザーが手動でスペースを解放する必要があることです。違いは、使用法と基礎となる原理という 2 つの側面から答えられます。
1. 使用方法
- 1. mallocとfreeは関数、newとdeleteは演算子です
- 2. malloc によって要求されたスペースは初期化されませんが、新しいスペースは初期化できます。
- 3. mallocがスペースに適用される場合、スペース サイズを手動で計算して渡す必要があります。Newの後にスペースの種類を指定するだけです。オブジェクトが複数ある場合は、[]にオブジェクトの数を指定するだけです。
- 4. mallocの戻り値はvoid* であり、使用する場合は強制する必要がありますが、newの後にスペースの型が続くため、 newは必要ありません。
2. 基礎となる原則
- malloc がスペースの適用に失敗すると、NULL が返されるため、使用するときは null にする必要があります。Newはその必要はありませんが、newは必要です
例外をキャッチするには
- カスタム タイプのオブジェクトを適用する場合、malloc/free はスペースを開くだけで、コンストラクターとデストラクターは呼び出しません。New はスペースの適用後にコンストラクターを呼び出してオブジェクトの初期化を完了し、delete は解放する前にデストラクターを呼び出します。スペース内のリソースのクリーンアップを完了する
要約する
この章では主に、C/C++ でのメモリ分散、malloc、realloc、calloc 関数、new/delete 演算子の使用法について概要を説明します。