C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++のnew/delete演算子を解説!動的メモリ確保と解放の基本


new演算子とは

new演算子は、ヒープ領域に対してメモリの割り当てを要求します。十分な空きメモリが存在する場合、確保したメモリをポインタ変数に結び付け、そのアドレスを返します。

基本構文

pointer_variable = new datatype;

初期値を指定して確保する構文

メモリ確保と同時に初期値を設定することも可能です。

pointer_variable = new datatype(value);

メモリブロック(配列)を確保する構文

pointer_variable = new datatype[size];

new演算子のサンプルコード

次の例では、単一の変数用のメモリ、初期値を指定して確保したメモリ、そして配列としてのメモリブロックを、それぞれnew演算子で確保しています。

#include <iostream>
using namespace std;

int main () {
    // int型1つ分のメモリを動的に確保
    int *ptr1 = NULL;
    ptr1 = new int;

    // float型のメモリを初期値223.324で確保
    float *ptr2 = new float(223.324);

    // int型28個分の配列としてメモリを確保
    int *ptr3 = new int[28];

    *ptr1 = 28;
    cout << "Value of pointer variable 1 : " << *ptr1 << endl;
    cout << "Value of pointer variable 2 : " << *ptr2 << endl;

    if (!ptr3)
        cout << "Allocation of memory failed\n";
    else {
        for (int i = 10; i < 15; i++)
            ptr3[i] = i + 1;
        cout << "Value of store in block of memory: ";
        for (int i = 10; i < 15; i++)
            cout << ptr3[i] << " ";
    }
    return 0;
}

実行結果:

Value of pointer variable 1 : 28
Value of pointer variable 2 : 223.324
Value of store in block of memory: 11 12 13 14 15

このコードでは、ptr1はint型1つ分、ptr2はfloat型1つ分(初期値223.324)、ptr3はint型28個分の領域をそれぞれ確保しています。ptr3にはインデックス10〜14に値を格納し、その内容を出力しています。

なお、標準C++ではnewによるメモリ確保に失敗するとstd::bad_alloc例外が送出されるため、確保の成否はtry-catch構文で確認するのが一般的です。また、近年のコードではNULLの代わりにnullptrを使用することが推奨されています。

delete演算子とは

delete演算子は、new演算子で確保したメモリを解放するために使用します。newで確保したメモリは自動的には解放されないため、不要になった時点でプログラマが明示的に解放する必要があります。解放を怠るとメモリリークの原因となるため、確保と解放は必ず対で行うようにしましょう。

基本構文

delete pointer_variable;

配列として確保したメモリを解放する構文

delete[ ] pointer_variable;

delete演算子のサンプルコード

先ほどの例に、確保したメモリをdelete演算子で解放する処理を追加したものが次のコードです。

#include <iostream>
using namespace std;

int main () {
    int *ptr1 = NULL;
    ptr1 = new int;
    float *ptr2 = new float(299.121);
    int *ptr3 = new int[28];

    *ptr1 = 28;
    cout << "Value of pointer variable 1 : " << *ptr1 << endl;
    cout << "Value of pointer variable 2 : " << *ptr2 << endl;

    if (!ptr3)
        cout << "Allocation of memory failed\n";
    else {
        for (int i = 10; i < 15; i++)
            ptr3[i] = i + 1;
        cout << "Value of store in block of memory: ";
        for (int i = 10; i < 15; i++)
            cout << ptr3[i] << " ";
    }

    // 確保したメモリを解放
    delete ptr1;
    delete ptr2;
    delete[] ptr3;

    return 0;
}

実行結果:

Value of pointer variable 1 : 28
Value of pointer variable 2 : 299.121
Value of store in block of memory: 11 12 13 14 15

単一のオブジェクトに対してはdeleteを、配列として確保した領域に対してはdelete[]を使用します。両者を混同すると未定義動作を引き起こす恐れがあるため、対応関係を正しく守ることが重要です。

まとめ

  • new演算子はヒープ領域から動的にメモリを確保し、そのアドレスを返す
  • 確保時に初期値の指定や、配列としての一括確保が可能
  • delete演算子で確保済みのメモリを明示的に解放する
  • 配列として確保したメモリは必ずdelete[]で解放する
  1. C++のインクリメント(++)・デクリメント(--)演算子のオーバーロード徹底解説

    C++には、インクリメント(++)とデクリメント(--)という2つの重要な単項演算子が用意されています。これらの演算子は、ユーザー定義クラスに対してオーバーロードすることで、オブジェクトを直感的に操作できるようになります。 次の例では、インクリメント演算子(++)を前置(prefix)と後置(postfix)の両方の使い方に対応させてオーバーロードする方法を解説します。同様の方法で、デクリメント演算子(--)もオーバーロード可能です。 前置と後置の違い 前置演算子(++T)は、値をインクリメントした後の値を返します。一方、後置演算子(T++)は、インクリメントする前の元の値を返してからインクリ

  2. C++のnew演算子で確保したメモリを初期化する方法

    C++のnew演算子は、メモリの「割り当て」を行うためのものであり、「初期化」まで自動的に行うものではありません。しかし、int型の配列をnewで動的に確保し、すべての要素をデフォルト値(intの場合は0)で初期化したい場合には、次のような構文を使用できます。基本構文:デフォルト初期化new int[10]();ポイントは、型名の後に空のかっこ () を付けることです。これにより、確保されたすべての要素がデフォルト初期化(ゼロクリア)されます。なお、この書き方では (0) のように具体的な値を指定したり、他の式を渡したりすることはできません。あくまで「デフォルト値での初期化」専用の構文である点