移动构造函数的意外调用
Unintended call of move constructor
我正在练习C++上面的代码移动语义代码,但是MemoryBlock
的值25
的移动构造函数被调用了两次。 之后,连续调用两次MemoryBlock
析构函数。
代码如下:
#include <iostream>
#include <vector>
class MemoryBlock {
private:
int length;
int* data;
public:
// Default constructor
MemoryBlock() = default;
// Constructor
explicit MemoryBlock(int p_length) : length(p_length), data(new int[length]) {
std::cout << "In MemoryBlock(int), length is " << length << ".n";
}
// Destructor
~MemoryBlock() {
std::cout << "~MemoryBlock() is called. Deleting resources.n";
delete[] data;
}
// Copy constructor
MemoryBlock(const MemoryBlock& other) : length(other.length), data(new int[other.length]) {
std::cout << "In MemoryBlock(const MemoryBlock&), length is " << length << ".n";
for (int i = 0; i < length; ++i) {
data[i] = other.data[i];
}
}
// Move constructor
MemoryBlock(MemoryBlock&& other) noexcept : length(0), data(nullptr) {
std::cout << "In MemoryBlock(MemoryBlock&&), length is " << other.length << ".n";
length = other.length;
data = other.data;
other.length = 0;
other.data = nullptr;
}
};
int main() {
std::vector<MemoryBlock> vec;
vec.push_back(MemoryBlock(25)); // (1)
vec.push_back(MemoryBlock(60)); // (2)
std::cout << "----------------- End of main() -----------------n";
return 0;
}
(现场试用(
结果:
In MemoryBlock(int), length is 25. // #1: Generate temporary object
In MemoryBlock(MemoryBlock&&), length is 25. // Move temporary object #1 to vec's node
~MemoryBlock() is called. Deleting resources. // Destruct temporary object #1
In MemoryBlock(int), length is 60. // #2: Generate temporary object
In MemoryBlock(MemoryBlock&&), length is 60. // Move temporary object #2 to vec's node
In MemoryBlock(MemoryBlock&&), length is 25. // ??
~MemoryBlock() is called. Deleting resources. // ??
~MemoryBlock() is called. Deleting resources. // ??
----------------- End of main() -----------------
~MemoryBlock() is called. Deleting resources. // Destruct vec's node 60
~MemoryBlock() is called. Deleting resources. // Destruct vec's node 25
我想知道为什么标有??
的行被调用。
最初代码中的 Vector 容量为零。它Allocator
是在push_back
时为一个对象分配内存。
vec.push_back(MemoryBlock(60)); // (2)
为2个元素分配新的内存块后,第一个元素被移动到新的内存块。
使用vec.reserve(2);
来避免这种情况。
似乎 std::vector 在内部使用了一些重新分配。这是在调用第二个"In MemoryBlock(MemoryBlock&&(,长度为 25">之前的调试器输出。
#0 MemoryBlock::MemoryBlock (this=0x419410, other=...) at memblock.cc:44
#1 0x0000000000401bba in __gnu_cxx::new_allocator<MemoryBlock>::construct<MemoryBlock, MemoryBlock> (this=0x7fffffffd6d0, __p=0x419410, __args#0=...) at /usr/include/c++/9/ext/new_allocator.h:147
#2 0x0000000000401819 in std::allocator_traits<std::allocator<MemoryBlock> >::construct<MemoryBlock, MemoryBlock> (__a=..., __p=0x419410, __args#0=...)
at /usr/include/c++/9/bits/alloc_traits.h:484
#3 0x0000000000402267 in std::__relocate_object_a<MemoryBlock, MemoryBlock, std::allocator<MemoryBlock> > (__dest=0x419410, __orig=0x4192f0, __alloc=...)
at /usr/include/c++/9/bits/stl_uninitialized.h:894
#4 0x000000000040216d in std::__relocate_a_1<MemoryBlock*, MemoryBlock*, std::allocator<MemoryBlock> > (__first=0x4192f0, __last=0x419300, __result=0x419410, __alloc=...)
at /usr/include/c++/9/bits/stl_uninitialized.h:932
#5 0x0000000000402056 in std::__relocate_a<MemoryBlock*, MemoryBlock*, std::allocator<MemoryBlock> > (__first=0x4192f0, __last=0x419300, __result=0x419410, __alloc=...)
at /usr/include/c++/9/bits/stl_uninitialized.h:946
#6 0x0000000000401ef2 in std::vector<MemoryBlock, std::allocator<MemoryBlock> >::_S_do_relocate (__first=0x4192f0, __last=0x419300, __result=0x419410, __alloc=...)
at /usr/include/c++/9/bits/stl_vector.h:453
#7 0x0000000000401d73 in std::vector<MemoryBlock, std::allocator<MemoryBlock> >::_S_relocate (__first=0x4192f0, __last=0x419300, __result=0x419410, __alloc=...)
at /usr/include/c++/9/bits/stl_vector.h:466
#8 0x000000000040195e in std::vector<MemoryBlock, std::allocator<MemoryBlock> >::_M_realloc_insert<MemoryBlock> (this=0x7fffffffd6d0, __position={length = 0, data = 0x101}, __args#0=...)
at /usr/include/c++/9/bits/vector.tcc:461
#9 0x000000000040176e in std::vector<MemoryBlock, std::allocator<MemoryBlock> >::emplace_back<MemoryBlock> (this=0x7fffffffd6d0, __args#0=...) at /usr/include/c++/9/bits/vector.tcc:121
#10 0x0000000000401606 in std::vector<MemoryBlock, std::allocator<MemoryBlock> >::push_back (this=0x7fffffffd6d0, __x=...) at /usr/include/c++/9/bits/stl_vector.h:1201
#11 0x000000000040128f in main () at memblock.cc:58
相关文章:
- C++析构函数被意外调用双链表
- 在gcc中意外调用了Const重载.编译器错误或兼容性修复程序
- 意外的 IConnectionPointImpl::不建议调用 Windows Embedded Compact 7
- C++意外调用继承类的函数
- 在调用 std::bind 的产品后意外调用析构函数
- 从 C++ 调用 cURL 命令会返回意外的错误代码,如 1792 和 6656
- 移动构造函数的意外调用
- 函数调用中出现意外编译错误 (C++)
- 基于范围的 std::move 调用意外复制构造函数
- 方法调用意外地像 l 值一样起作用
- 未声明的标识符和类型"int"从 main 调用类时出现意外错误
- 通过 lambda 调用成员函数时意外未初始化的数据
- 使用默认构造函数的父类;子类的析构函数意外调用
- 子类调用意外的重载函数
- 从指针返回对象时出现意外的析构函数调用
- 在X64模式下从C /CLI调用MASM PROC会产生意外的性能问题
- 与move构造函数配对时,会发生意外的析构函数调用
- CPP 多重继承意外调用 CTOR
- 当我在递归函数中调用 return 时,我的程序意外完成
- 程序不断调用意外和终止函数