C++プログラミングのメモリ分割モデル(コード領域、グローバル領域、スタック領域、ヒープ領域)

序文

以前に習ってメモをとったので、改めて整理して補足し、自分なりに復習していきますので、皆様のお役に立てれば幸いです。


メモリ パーティション モデル

  1. コード領域: オペレーティング システムによって管理される、関数本体のバイナリ コードを格納します
    格納されているすべてのコード
  2. グローバル領域:グローバル変数静的変数および定数を格納します
  3. スタック領域: コンパイラによって自動的に割り当てられ、解放されます。関数のパラメーター値、ローカル変数などを保存します。
  4. ヒープ領域: プログラマーによって割り当てられ、解放されます。プログラマーが解放しない場合、プログラムの最後にオペレーティング システムによって再利用されます。

コード領域とグローバル領域はプログラム実行前の領域
で、ヒープ領域とスタック領域はプログラム実行後の領域です。

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;

要約:

  1. C++ は、プログラム実行前にグローバル領域とコード領域に分割されます
  2. コード領域は、共有および読み取り専用として特徴付けられます
  3. グローバル領域にはグローバル変数が格納されます。 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;
}

要約:

  1. ヒープ領域のデータを解放するには、delete キーワードを使用します。
  2. ポインターを解放するときは、p を直接削除します。
  3. データを解放するとき、[] 配列を削除します。
  4. ヒープ領域に格納されたデータは、プログラマーによって手動で作成 (新規) および解放 (削除) されます。

おすすめ

転載: blog.csdn.net/cyaya6/article/details/128218361