C++のnewとdelete

19446 ワード

一、newとdelete:
(1)newはオペレータであり,関数ではなくmallocは関数である.
(2)基本データ型(int,float,double,char),free,malloc,new,deleteの効果は一致する.
(3)delete,freeは基本データ型に対して,2回解放してもエラーが発生する.
(4)freeの後、ポインタの値は変わらず、deleteの後、ポインタの値は変わる(私のパソコンではdeleteのたびにポインタの値が0000 8123になった)が、freeの後のポインタの値は変わらず、印刷されたのはゴミ値である.freeの後、迷路ポインタを避けるために、ポインタを空ポインタ(nullptr)に設定したほうがよい.
(5)基本データ型newであればコンストラクション関数は呼び出されず,deleteではコンストラクション関数は呼び出されない.
構造タイプの場合、newはコンストラクション関数を呼び出し、deleteはコンストラクション関数を呼び出します.
(6)基本データ型配列,delete,delete[]一致;基本データ型,互いに混合して使用できる.
(7)複合データ型(delete,delete[]は混在できない)
例:mydata*p(new mydata);   delete p;
mydata *p(new mydata[10]);    delete[] p;
(8)個々のスタック上のオブジェクトは,delete[]を用いることができず,deleteを繰り返すことができず,次のdeletコードは誤りであり,delete pのみを用いることができ,delete[]pを用いることができない.
mydata *p(new mydata);
delete [ ]  p;//単一のスタック上のオブジェクトはdelete[]を使用してはいけません.delete[]プログラムを使用するとエラーが発生します.
#include<iostream>
using namespace std;

void main2()
{
    int *p1 = new int(4);//      
    int *p2 = new int[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };//    
    delete p1;//delete p1    int *p1 = new int(4);
    delete[] p2;//delete[] p2  int *p2 = new int[10]{ 1,2,3,4,5,6,7,8,9,0 };
    
    cin.get();
}

// new
void main3() { int *p = new int[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; cout << p << endl; cout << "--------------" << endl; delete[] p; cin.get(); }

// new
void main4() { int *p1 = new int(4); cout << p1 << endl; cout << "--------------" << endl; delete p1;//delete[] p1; cin.get(); }
class mydata { public: mydata() // { cout << "create" << endl; } ~mydata()// { cout << "delete" << endl; } };
void main() { mydata *p(new mydata); delete p; //mydata *p(new mydata); //delete []p;// , delete [], delete mydata *p(new mydata[10]); delete []p;// cin.get(); }

二、位置決めnew演算子:
位置決めnew演算子はnew演算子の変形です.通常、newはメモリを開くためにスタック領域にあり、必要に応じてnewはスタック領域と静的領域にも空間を開くことができる.
位置決めnew演算子を使用するには、newヘッダファイル#includeを含めます.
#include <iostream>
#include <new>

using namespace std;

const int BUF = 512;
const int N = 5;
char buffer[BUF];

int main()
{
    double *p1, *p2;

    cout << "calling new and placement new " << endl;
    p1 = new double[N];
    p2 = new (buffer) double[N];
    for (int i = 0; i < N; i++)
    {
        p2[i] = p1[i] = 1000 + 10.0*i;
    }
    cout << "heap:"<<p1<< "      static:"<<(void*)buffer << endl;
    cout << "memory contents:" << endl;
    for (int i = 0; i < N;i++)
    {
        cout <<" p1  "<< p1[i] << " at " << &p1[i] << ";   ";
        cout << " p2  "<<p2[i] << " at " << &p2[i] << endl;
    }

    cout << "   " << endl;
    cout << "calling new and placement new a second time" << endl;
    double *p3, *p4;
    p3 = new double[N];
    p4 = new (buffer) double[N];//    
    for (int i = 0; i < N; i++)
    {
        p4[i] = p3[i] = 1000 + 50.0*i;
    }

    cout << "memory contents:" << endl;
    for (int i = 0; i < N; i++)
    {
        cout << "p3  "<<p3[i] << " at " << &p3[i] << ";   ";
        cout << "p4  " << p4[i] << " at " << &p4[i] << endl;
    }

    cout << "   " << endl;
    cout << "calling new and placement new a third time" << endl;
    delete [] p1;
    p1 = new double[N];
    p2 = new(buffer + N*sizeof(double)) double[N];
    for (int i = 0; i < N; i++)
    {
        p2[i] = p1[i] = 1000 + 70.0*i;
    }
    
    cout << "memory contents:" << endl;

    for (int i = 0; i < N; i++)
    {
        cout <<"p1 "<< p1[i] << " at " << &p1[i] << ";   ";
        cout << "p2"<<p2[i] << " at " << &p2[i] << endl;
    }

    delete[]p1;
    delete[]p3;
    

    cin.get();
    return 0;
}

 
実行結果:
calling new and placement new
heap:007AB2F8      static:01380320
memory contents:
 p1  1000 at 007AB2F8;    p2  1000 at 01380320
 p1  1010 at 007AB300;    p2  1010 at 01380328
 p1  1020 at 007AB308;    p2  1020 at 01380330
 p1  1030 at 007AB310;    p2  1030 at 01380338
 p1  1040 at 007AB318;    p2  1040 at 01380340

calling new and placement new a second time
memory contents:
p3  1000 at 007AB500;   p4  1000 at 01380320
p3  1050 at 007AB508;   p4  1050 at 01380328
p3  1100 at 007AB510;   p4  1100 at 01380330
p3  1150 at 007AB518;   p4  1150 at 01380338
p3  1200 at 007AB520;   p4  1200 at 01380340

calling new and placement new a third time
memory contents:
p1 1000 at 007AB2F8;   p21000 at 01380348
p1 1070 at 007AB300;   p21070 at 01380350
p1 1140 at 007AB308;   p21140 at 01380358
p1 1210 at 007AB310;   p21210 at 01380360
p1 1280 at 007AB318;   p21280 at 01380368

new演算子を位置決めし、p 2を配列bufferに配置し、p 2とbufferのアドレスは01380320である.しかし、彼らのタイプは異なり、p 2はdoubleのポインタであり、bufferはcharのポインタである.だからvoid*でbufferをタイプ変換して、さもなくばbufferは1つの文字を印刷します.
最後に、bufferはメモリの静的メモリを指定するため、deleteはスタック領域の割り当てられたメモリしか解放できません.