【发布时间】:2019-10-05 19:38:13
【问题描述】:
我的 C++ 代码中有一个类,它有自己的移动构造函数。此处显示了简化版本:
class myClass {
//In this example, myClass must manually manage allocating
//and freeing a memory buffer.
char *mem;
//...
//Regular constructor, copy constructor, etc
//...
myClass(myClass &&other) {
//Swap our memory pointer with other's memory pointer
char *tmp = other.mem;
other.mem = mem;
mem = tmp;
}
//...
//Destructor, other member functions, etc.
//...
}
在正常情况下,这可以正常工作。但是,最近我需要制作这些对象的向量:
vector<myClass> v;
v.reserve(10); //Make space, but do not construct
v.push_back(myClass()); //Problem!
在遇到段错误并逐步使用 gdb 后,我最终发现了应该很明显的事情:如果您尝试从右值引用构造对象,这可能会导致在未初始化的内存上使用移动构造函数时间>。
当您可能将垃圾交换到other 类中时,您应该如何编写移动构造函数?有什么方法可以检测到这一点吗?
【问题讨论】:
-
你需要内存缓冲区,还是真的需要
std::string? -
为了在论坛上提问,我简化了这个例子。在极少数情况下,您确实想管理自己的记忆。无论如何,std::string 是如何解决这个问题的?
-
我认为您需要向我们展示常规的无参数构造函数。大概它初始化
mem,如果只是nullptr? (另外,在您的复制构造函数中没有理由使用other.mem = mem;更好的是free (mem); mem = other.mem; other.mem = nullptr;) -
构造函数总是被应用于未初始化的内存。所以不要交换指针。只需将其复制到正在构造的对象并将移动的指针设置为 0。
-
@Mahkoe 在初始化内存上调用构造函数是未定义的行为。您正在访问未初始化指针 (
mem) 的值。
标签: c++ stdvector move-semantics