【发布时间】:2017-01-02 02:44:16
【问题描述】:
在以下情况下,我的对象超出范围并且我访问了一个无效的指针:
struct Animal
{
char* buffer;
Animal() { buffer = new char[100]; }
~Animal() { delete[]buffer; }
};
int main()
{
vector<Animal> list;
{
Animal dog;
list.push_back(dog);
}
list[0].buffer[50] = 7; // Buffer's been deleted, can't access it
}
我想防止这种情况的最佳方法是在向量中适当地构造 Animal 对象,但我不知道该怎么做。我想过做:
list.push_back(Dog());
但这仍然会创建一个临时的,除非它被优化掉,我宁愿不依赖它,因为在另一个地方(另一个编译器)它可能不会做同样的事情。
编辑:感谢 Remy Lebeau,我了解到您可以直接在矢量中构造矢量元素,无需临时,无需复制,具有以下功能:
template< class... Args >
void emplace_back( Args&&... args );
我不知道可变参数模板参数是如何工作的,但描述是:
将一个新元素附加到容器的末尾。元素是 通过 std::allocator_traits::construct 构造,通常 使用placement-new在该位置就地构造元素 由容器提供。参数 args... 被转发到 构造函数为 std::forward(args)....
【问题讨论】:
-
我不明白这个问题。您是否要求将不可默认构造的内容放入
std::vector? -
reserve()不是这样做的。 -
“之后我使用我的 vectorOfAnimals[0] 并访问了一个无效的指针” 你对“无效指针”是什么意思?它在哪里?
-
对不起,我最好重写问题
-
@TitoneMaurice 您想通过使用矢量来防止这些问题,但是 IMO 您只专注于矢量会走错方向。向量刚刚暴露了你班级的问题。要么修复复制问题(通过使用
std::vector<char>或std::string很容易完成),或者通过将复制操作设为私有和未实现来使类不可复制,或者使用C++ 11 的= delete语法。跨度>
标签: c++ vector scope copy raii