メモリ パーティション モデル
序文
以前に習ってメモをとったので、改めて整理して補足し、自分なりに復習していきますので、皆様のお役に立てれば幸いです。
メモリ パーティション モデル
- コード領域: オペレーティング システムによって管理される、関数本体のバイナリ コードを格納します
格納されているすべてのコード - グローバル領域:グローバル変数と静的変数および定数を格納します
- スタック領域: コンパイラによって自動的に割り当てられ、解放されます。関数のパラメーター値、ローカル変数などを保存します。
- ヒープ領域: プログラマーによって割り当てられ、解放されます。プログラマーが解放しない場合、プログラムの最後にオペレーティング システムによって再利用されます。
コード領域とグローバル領域はプログラム実行前の領域
で、ヒープ領域とスタック領域はプログラム実行後の領域です。
4つのメモリーエリアの意味:
さまざまな領域に格納されたデータにはさまざまなライフサイクルが与えられているため、柔軟にプログラミングできます。
プログラム実行前
プログラムがコンパイルされると、コンパイル可能なexe実行プログラムが生成され、プログラムが実行される前に2つの領域に分割されます
コードエリア:
- CPU によって実行されるマシン命令を格納します。
- The code area is shared . 共有の目的は、頻繁に実行されるプログラムの場合、メモリ内に必要なコードのコピーが 1 つだけで済むようにすることです。
- The code area is read-only . 読み取り専用の理由は、プログラムが誤って命令を変更するのを防ぐためです。
大域ゾーン:
- グローバル変数と静的変数を保存する
- グローバル領域には、文字列定数やその他の定数 (const によって変更されるグローバル変数)も格納される定数領域も含まれます。
- この領域のデータは、プログラムの実行が終了した後、オペレーティング システムによって解放されます。
ローカルに変更された変数または定数がある限り、それらはグローバル領域にはありません.
例: const によって変更されたローカル変数
/*
* @Author: _oufen
* @Date: 2022-11-17 00:29:53
* @LastEditTime: 2022-11-17 00:51:52
* @Description:
*/
#include <iostream>
using namespace std;
//全局变量
int global_a = 10;
int global_b = 10;
/*全局常量*/
const int c_g_a = 10;
const int c_g_b = 10;
int main()
{
/*全局变量 静态变量 常量 存放在全局区*/
// 局部变量
int a = 10;
int b = 10;
cout << "局部变量a的地址:" << (long long)&a << endl;
cout << "局部变量b的地址:" << (long long)&b << endl;
/*全局变量*/
cout << "全局变量a的地址:" << (long long)&global_a << endl;
cout << "全局变量b的地址:" << (long long)&global_b << endl;
/*静态变量*/
static int sta_a = 10;
static int sta_b = 10;
cout << "静态变量a的地址:" << (long long)&sta_a << endl;
cout << "静态变量b的地址:" << (long long)&sta_b << endl;
/*常量*/
// 1. 字符串常量
cout << "字符串常量的地址为:" << (long long)&"helloworld" << endl;
// 2. const 修饰的局部变量
const int con_a = 10;
const int con_b = 10;
cout << "const 修饰变量a的地址:" << (long long)&con_a << endl;
cout << "const 修饰变量b的地址:" << (long long)&con_b << endl;
/*全局常量*/
cout << "全局常量c_g_a的地址 :" << (long long)&c_g_a << endl;
cout << "全局常量c_g_b的地址 :" << (long long)&c_g_b << endl;
system("pause");
return 0;
}
スクリーンショットを実行します。
通过上面的例子可以总结出
大域ゾーンには以下が格納されます。
- グローバル変数
int c_g_a=10;
- 静的変数
static int sta_a=10;
- 絶え間ない含む文字列定数
"helloworld"
とグローバル定数const int c_g_a=10;
要約:
- C++ は、プログラム実行前にグローバル領域とコード領域に分割されます
- コード領域は、共有および読み取り専用として特徴付けられます
- グローバル領域にはグローバル変数が格納されます。 static 変数 文字列定数 const で変更されたグローバル変数
プログラムの実行後
スタックエリア:
コンパイラによって自動的に割り当てられ、解放され、関数のパラメーター値、ローカル変数などを格納します。
予防、ローカル変数のアドレスを返さない、スタック領域に作成されたデータはコンパイラによって自動的に解放されます
/*
* @Author: _oufen
* @Date: 2022-11-17 10:55:15
* @LastEditTime: 2022-11-17 10:56:46
* @Description:栈区
*/
#include <iostream>
using namespace std;
int *funca(int b) //形参也存放在栈区
{
int f_a = 10; //局部变量 存放在栈区,栈区中的数据在函数执行完后自动释放
return &f_a; //返回局部变量的地址 会报错
// warning: address of local variable 'a' returned [-Wreturn-local-addr]
}
int main()
{
int *p = funca(1);
cout << "*p = " << *p << endl;
cout << "*p = " << *p << endl;
system("pause");
return 0;
}
ヒープ領域:
プログラマーによって割り当てられ、解放されます。プログラマーが解放しない場合、プログラムの最後にオペレーティング システムによって再利用されます。
C++では、newは主にヒープ領域のメモリを開放するために使用されます
ヒープ領域のデータは解放されず、ポインタでヒープ領域を指すことでヒープ領域のデータを使用できます。
ヒープ領域のデータはプログラマが確保・解放
/*
* @Author: _oufen
* @Date: 2022-11-17 10:55:15
* @LastEditTime: 2022-11-17 11:10:57
* @Description:堆区
*/
#include <iostream>
using namespace std;
int *func()
{
/*利new关键字,可以将数据开辟到堆区*/
//指针也是局部变量 放在栈区 指针保存的数据放在堆区
//堆区的地址用栈上的指针保存
// new关键字可以创建堆区的数据
// 返回的是创建堆区数据的地址
int *p = new int(10); // new int (10) 在堆区开辟了一段内存,将这段内存的编号返回,指针p接收这段内存
return p;
}
int main()
{
//堆区开辟数据
int *p = func();
cout << "*p = " << *p << endl;
cout << "*p = " << *p << endl;
cout << "*p = " << *p << endl;
cout << "*p = " << *p << endl;
system("pause");
return 0;
}
new 演算子はヒープ データを開きます
c++ ではnew 演算子を使用してヒープ領域のデータを開き、格納されたデータはヒープ領域にあります。
ヒープ領域に展開されたデータは、プログラマーが手動で展開し、手動で解放し、オペレーターを使用して解放します。消去
文法:
new データ型
new によって作成されたデータは、対応するデータ型のポインタを返します
/*
* @Author: _oufen
* @Date: 2022-11-17 11:19:37
* @LastEditTime: 2022-11-17 11:32:40
* @Description: new操作符开辟堆区数据
*/
#include <iostream>
using namespace std;
int *func1()
{
//在堆区创建整形数据
// new返回的是创建堆区数据类型的指针
int *p = new int(10);
return p;
}
void func2()
{
//在堆区使用new开辟数组
// int *arr = new int[10]; 在堆区开辟了空间为10的数组
int *array = new int[5]{
1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++)
{
cout << array[i] << endl;
}
//释放堆区的数组
//释放数组的时候,要加[]
delete[] array;
}
int main()
{
int *p = func1();
// 堆区的数据由程序猿来 开辟 也由程序猿来 释放
// 可以使用delete关键字来释放堆区数据
cout << "*p = " << *p << endl;
cout << "*p = " << *p << endl;
cout << "*p = " << *p << endl;
delete (p); //释放了堆区数据
// cout << "*p = " << *p << endl; //*p = 900995024
func2();
system("pause");
return 0;
}
要約:
- ヒープ領域のデータを解放するには、delete キーワードを使用します。
- ポインターを解放するときは、p を直接削除します。
- データを解放するとき、[] 配列を削除します。
- ヒープ領域に格納されたデータは、プログラマーによって手動で作成 (新規) および解放 (削除) されます。