c ++ - :: operator new []和我的自定义容器的分配

时间:2015-09-27 16:32:22

标签: c++ arrays containers new-operator allocation

我遇到了一个无法解决问题的问题。 我正在编写自己的容器,这或多或少像std::vector<T>,我不知道如何解决为对象分配内存的问题。

让我们说,例如,我在数组周围编写了一个包装器,并希望像这样分配数据:

T* cArray = new T[size];
cArray[index] = std::move(obj);

如果obj没有默认构造函数,它没有采取任何参数,则会收到错误:&#34;类:没有合适的默认构造函数&#34;。

所以我虽然可以通过使用operator new static_cast<T*>(::operator new(sizeof(T)*this->cap))来调用obj的构造函数来解决问题,但只有当我使用像int, double and floats这样的内置类型作为成员时,这才有用。我的测试对象。<​​/ p>

如果我这样做:

struct Test
{
    Test(int x){}
    std::string s;
    double d;
}

MyVector<Test> vec;
vec.push_back(Test(1));

如果我尝试将数据分配给push_back函数中包含以下行的位置,则会出现运行时错误:

cArray[index] = std::move(obj);
文件中的

:第106行的xmemory0:

  

Expression: "(_Ptr_user & (_BIG_ALLOCATION_ALIGNMENT -1)) == 0

同样,当我不使用内置类型时,这只是一个问题。如果我删除std::string作为成员,一切都按预期工作。我不知道问题的原因是什么,也不知道如何在数小时的搜索后解决问题。

你们知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

一个答案是不存储T[],而是存储具有相同大小和对齐要求的内容(通常选择aligned_storage)。然后使用placement new运算符构造其中的项目,例如

new (&carray[index]) T(...args)

完成项目后,需要在每个项目上手动调用析构函数。

答案 1 :(得分:0)

这是分配内存的正确方法。但是你仍然需要最终调用构造函数,将空字节转换为对象。 (稍后你需要调用析构函数。)

您需要使用&#34;展示新的&#34;调用构造函数:

new (&carray[index]) Test(obj)

答案 2 :(得分:0)

你有正确的想法,至少是它的前半部分。哪个是分配原始内存,而不是使用new Test[N]。但是你仍然需要构建你的对象,你可以使用placement new来做。给定指针p指向您想要构造对象的位置,您可以这样做:

new (p) Test(...constructor args...);

另请注意,完成对象后,您需要手动调用析构函数:

p->~Test();