C++ placement new

C++ placement new

本文关键字:new placement C++      更新时间:2023-10-16

如果这个问题听起来很愚蠢,我很抱歉,但我刚刚开始学习C++,关于新的放置有一些让我困惑的地方

我一直在读C++初级读本(我觉得这是一本学习C++的非常好的书),在新的位置部分有一个例子。该示例使用字符数组为放置新提供内存空间

const int BUF = 512;
const int N = 5;
char buffer[BUF];
double * pd1;
pd1 = new (buffer) double[N];

我的问题是,为什么它使用char数组来为放置new提供内存空间?此外,上面代码的最后一行是为double数组分配内存,当原始内存空间包含char数组时,这怎么可能呢?如果placement new使用的是char数组的内存空间,这是否意味着当我们分配双数组时,它会覆盖该内存中的char数组?

如果这个问题很奇怪,我再次表示抱歉,但希望我已经说得很清楚了。

为什么要使用char数组为新的放置提供内存空间?

为什么不呢?char是C++定义的最小类型,在几乎每个实现中,它的大小都是一个字节。因此,当您需要分配一定大小的内存块时,它是一个很好的类型。

C++也有关于如何分配char数组的非常具体的机制(并且char)。例如,new char[*]不会与char的对齐对齐。它将与任何类型的最大正常对齐对齐。因此,您可以使用它来分配内存,然后将任何类型构造到该内存中。

此外,上面代码的最后一行是为double数组分配内存,当原始内存空间包含char数组时,这怎么可能呢?

它没有分配任何内容。它是用你给它的内存构造一个数组。这就是placement new的作用,它在提供的内存中构造一个对象。

如果placement new使用的是char数组的内存空间,这是否意味着当我们分配双数组时,它会覆盖该内存中的char数组?

是。

是的,char数组和double数组将重叠,更具体地说,它们将从内存中的同一地址开始,即(long)buffer(long)pd1将相同。我们可以通过使字节大小匹配(假设sizeof(char) == 1)来更加强调重叠:

const int N = 5;
char buffer[N * sizeof(double)];
double *pd1 = new (buffer) double[N];

是的,如果修改pd1指向的数据,则也会修改buffer指向的数据。反之亦然。(另请参阅GCC标志-fstrict-aliasing,了解编译器优化如何处理这种重叠。)

没有愚蠢的问题。

它使用char可能是因为它让您考虑原始字节(char通常为1字节长)。代码的最后一行没有分配内存,它只是在提到的缓冲区上放置了一个双数组。如果它是一个对象,它也会调用构造函数。是的,char数组会被覆盖。

内存就是内存。机器并不关心存储在那里的数据类型,这取决于语言的定义和强制执行。"为什么"的答案是"因为C++是为了让你。">

char buffer[BUF];只是一些内存。组成缓冲区的字节没有附加任何类型信息。只有编译器知道,这个内存区域应该包含字符。你可以使用任何类型,甚至双:

double buffer[BUF];
double *pd1 = new (buffer) double[N];