我正在使用C++,并且具有以下结构:

struct ArrayOfThese {
诠释
int b;
};

struct DataPoint {
诠释
int b;
int c;
};

在内存中,我希望每个DataPoint的末尾具有1个或多个ArrayOfThese元素。每个DataPoint的ArrayOfThese元素数量并不总是相同。

因为要组装然后在网络上传输的DataPoints数量很多,所以我希望所有DataPoints及其ArrayOfThese元素都是连续的。浪费一定数量的ArrayOfThese元素的空间是 Not Acceptable 。

在C语言中,我将在DataPoint的末尾创建一个元素,声明为ArrayOfThese d[0];,为我拥有的许多ArrayOfThese元素分配一个DataPoint加上足够的额外字节,并使用虚拟数组对其进行索引。 (当然,ArrayOfThese元素的数量必须在DataPoint的字段中。)

在C++中,是否使用新的位置和相同的0长度数组来破解是正确的方法?如果是这样,placement new是否保证从同一内存池对new的后续调用将连续分配?

最佳答案

由于您的结构是POD,因此您也可以像在C中一样进行操作。唯一需要的是强制类型转换。假设n是要分配的事物数:

DataPoint *p=static_cast<DataPoint *>(malloc(sizeof(DataPoint)+n*sizeof(ArrayOfThese)));

如果您的对象具有非平凡的构造函数,则new确实会出现这种情况。但是,它不保证任何分配,因为它不分配自身,并且要求已经以某种方式分配了内存。相反,它将传入的内存块视为尚未构造的对象的空间,然后调用正确的构造函数来构造它。如果要使用它,代码可能会像这样。假设DataPoint具有您建议的ArrayOfThese arr[0]成员:
void *p=malloc(sizeof(DataPoint)+n*sizeof(ArrayOfThese));
DataPoint *dp=new(p) DataPoint;
for(size_t i=0;i<n;++i)
    new(&dp->arr[i]) ArrayOfThese;

构造的内容必须被破坏,因此,如果执行此操作,那么您也应该理清析构函数的调用。

(我个人建议在这种情况下使用POD,因为它消除了调用构造函数和析构函数的任何需要,但是如果您小心的话,这种事情可以合理地安全地完成。)

10-08 01:36