通常,new负责在堆(heap)中找到一个足以能够满足要求的内存块。new运算符还有一种变体,被称为定位(placement)new运算符,它能让我们向编译器指定要使用的位置。
程序员可以使用这种特性来设置其内存管理规程,处理需要通过特定地址进行访问的硬件或者在特定位置创建对象。
要使用这一特性,必须包含new头文件(但实际上我发现没有包含new也能运行成功)
#include<iostream>
#include<cstring>
#include<new>
using namespace std;
struct student
{
char name[20];
int age;
};
int buffer1[20];
char buffer2[200];
int main()
{
student *s1,*s2;
int *i1,*i2;
//常规使用方法
i1 = new int(5);
s1 = new student;
strcpy(s1->name, "dgh");
s1->age = 20;
//在指定的内存位置申请动态内存
i2 = new(buffer1) int (9);
s2 = new(buffer2) student;
strcpy(s2->name,"dgx");
s2->age = 12;
cout << buffer1[0] << endl;
cout << buffer2;
}
输出:
[Running] cd "d:\程序\随笔程序\2020年1月\" && g++ new.cpp -o new && "d:\程序\随笔程序\2020年1月\"new
9
dgx
在常规方法中,我们只是能够动态申请一段内存并返回指向它的一个指针,使用定位new运算符之后,我们可以在自己指定的一段内存中动态申请,我们甚至还可以使用原有内存的地址来访问我们新申请之后存入的值,比如上面程序中的语句:
cout << buffer1[0] << endl; cout << buffer2;
工作原理
定位new运算符的原理就是,只是返回传递给它的地址,并将其强制转换为void*
类型,以便于赋值给任何指针类型。