C++new与定位new

C++new运算符与定位new运算符

1.new运算符和new[]运算符

new运算符会根据所给类型动态分配内存(在堆中),然后返回首地址

A.动态分配基本类型和基本类型的数组

//基本类型
    //仅分配空间,不初始化    
    typeName * pointer = new typeName;
    //例:
    int * pint = new int;

    //分配空间,同时初始化
    typeName * pointer = new typeName(value);
    //例:
    int * pint = new int(3);    //分配一个整型空间,初始化为3

//基本类型数组
    typeName * parray = new typeName[SIZE];
    //例:
    int * parray = new int[5];  //分配长度为5的动态整型数组

B.动态分配类对象

//分配内存后调用无参构造
//分配内存后调用有参数默认值的有参构造
className * pobj = new className();

//分配内存后调用有参构造
className * pobj = new className(参数列表);

C.使用delete释放

  1. 通过new运算符分配的内存,使用delete释放
  2. 通过new[]运算符分配的内存(数组),通过delete[]释放
  3. 动态分配的内存只可以释放一次

2.定位new

定位new可以在指定的位置分配内存

A.和普通new的区别

需要在指定一个分配的位置,也就是说从哪里开始分配

例:

char buffer[256];
int * pint = new(buffer) int;
int * parray = new(buferr) int[5];
A * pa = new(buffer) A();   //A为自定义的类

B.一个问题

int main() {

    char buffer[256];
    cout << (void *)buffer << endl;

    int * pint = new(buffer) int;
    cout << pint << endl;

    int * parray = new(buffer) int[5];
    cout << parray << endl;

    A * pa = new(buffer) A();
    cout << parray << endl;
    return 0;
}

输出: 004FFC54 004FFC54 004FFC54 004FFC54 可见,定位的new并不智能,永远只从我们指定的地方开始

解决:

int main() {

    char buffer[256];
    cout << (void *)buffer << endl;
    char *p = buffer;

    int * pint = new(p) int;
    p += sizeof(int);
    cout << pint << endl;

    int * parray = new(p) int[5];
    p += sizeof(int[5]);
    cout << parray << endl;

    A * pa = new(p) A();
    p += sizeof(A);
    cout << pa << endl;
    pa->~A();
    return 0;
}

C.释放——放buffer即可

I>基础类型

由于我们是在buffer已经分配的基础上分配,所以,释放buffer即可
上述例子中,buffer在代码块结束后,会自动释放;
如果buffer通过new分配,则需要使用delete释放

II>类对象

可能大家注意到了,上述例子中,我们显式调用了对象的析构函数。 类在释放自己的空间前,会自动调用析构函数,但是在定位new这里,不能通过delete 语句释放对象,所以,对象就不能隐式的调用析构函数,需要在buffer释放前,显式的调用析构函数

猜你喜欢

转载自blog.csdn.net/qq2071114140/article/details/89287373
new
今日推荐