initializer_list与2013中的双重删除
Double delete in initializer_list vs 2013
今天在我的项目中遇到了一个内存问题,其中一个类使用c++11 initializer_list。系统发出内存问题的信号:"dbgdel.cpp中的Expression _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)。我将代码简化为一个简单的例子,它不再抛出表达式,但问题从调试输出中变得明显。在我看来,这段代码是正确的,而且它似乎可以与g++一起工作。
#include <functional>
#include <memory>
#include <string>
#include <iostream>
#include <vector>
#include <map>
#include <sstream>
#include <initializer_list>
using namespace std;
class B {
public:
char data[256];
B(const string& x) {
cout << "Init " << this << endl;
}
B(const B& b) {
cout << "Copy " << this << endl;
}
~B() {
cout << "Deleting b " << this << endl;
}
};
class C {
public:
vector<B> bs;
C(initializer_list<B> bb) {
for(auto& b : bb) {
bs.push_back(b);
}
}
};
int main(int argc, char** argv) {
C bb { B("foo"), B("bar") };
return 0;
}
输出为:
初始化00B7FAE8初始化00B7FBE8副本00E108A0复制00E10AE8(????)删除b 00E108A0复制00E10BE8删除b 00B7FBE8删除b 00B7FAE8正在删除b 00B7FAE8(已删除两次!)
我在这里犯了什么错误,或者这不应该起作用?
至于使用您看到的额外副本,这是由初始化过程中的向量大小调整引起的。以下是您的流程:
Init 00B7FAE8 // construct "foo"
Init 00B7FBE8 // construct "bar"
Copy 00E108A0 // copy "foo" to vector (capacity=1)
Copy 00E10AE8 (?????) // copy the above object to the resized vector (capacity = 2)
Deleting b 00E108A0 // delete the smaller vector buffer
Copy 00E10BE8 // copy "bar" from initialization_list to vector
Deleting b 00B7FBE8 // delete initialization_list in reverse order. this is "bar"
Deleting b 00B7FAE8 // last to delete. this is "foo"
Deleting b 00B7FAE8 (bug)
// later C::bs is destroyed
您可以在这里看到的是,由于复制的原因,通过push_back初始化向量的速度相当慢。即使你使用了更优雅的方式,这种情况也会发生:
C(initializer_list<B> bb) : bs(bb) {}
一种更快(没有额外副本)的方法是:
C(initializer_list<B> bb) {
bs.reserve(bb.size());
bs.insert(bs.end(), bb.begin(), bb.end());
}
相关文章:
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 当提供用户定义的移动构造函数时,Visual Studio 2013不会删除复制构造函数
- 如何在visual C++2013上递归删除二叉树
- initializer_list与2013中的双重删除
- [微软 VS 2013]C++在删除运算符"Debug Assertion Failed!"时失败
- unique_ptr无法删除SDL_Window,因为它是不完整的类型(VC++ Express 2013)