我遇到了一个无法解决问题的问题。
我正在编写自己的容器,这或多或少像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
作为成员,一切都按预期工作。我不知道问题的原因是什么,也不知道如何在数小时的搜索后解决问题。
你们知道如何解决这个问题吗?
答案 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();