6

抱歉,如果这个问题听起来很愚蠢,但我刚刚开始学习 C++,而且我对新的位置感到困惑

我一直在阅读 C++ Primer(我发现这是一本非常好的学习 C++ 的书),并且在安置新部分中给出了一个示例。该示例使用 char 数组为放置 new 提供内存空间

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

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

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

4

5 回答 5

7

为什么它使用 char 数组来为放置 new 提供内存空间?

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

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

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

它没有分配任何东西。它正在使用您给它的内存构造一个数组。这就是placement new 所做的,它在提供的内存中构造一个对象。

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

是的。

于 2012-11-13T23:58:40.033 回答
3

是的,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以了解编译器优化如何处理这种重叠。)

于 2012-11-13T23:57:54.373 回答
2

没有愚蠢的问题。

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

于 2012-11-13T23:57:06.523 回答
1

记忆就是记忆。机器不关心存储在那里的数据类型,这取决于定义和执行的语言。“为什么”的答案是“因为 C++ 旨在让你”。

于 2012-11-13T23:57:27.577 回答
0

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

double buffer[BUF];
double *pd1 = new (buffer) double[N];
于 2012-11-14T00:00:44.093 回答