如何禁止或阻止传递堆栈分配的变量
How do I disallow or block the passing of stack allocated variables?
我有一个类使用std::forward_list,比如so:
void Foo::AddBar(Bar* _bar)
{
Bars.push_front(_bar);
}
void Foo::DeleteBar(Bar* _bar)
{
for (forward_list::iterator index = Bars.begin(); index != Bars.end(); ++index)
{
if (_bar == *index)
{
delete _bar;
forward_list.remove(_bar);
}
}
}
如果我传递一个堆栈分配的变量,在调试/发布中它会给我一个运行时错误,在生产中它会"破坏"堆。
Bar bar;
foo.AddBar(&bar);
foo.DeleteBar(&bar); // Memory corruption on "delete _bar"
如何防止Foo::AddBar接受堆栈分配的数据?有更好的设计方法吗?
编辑2013年6月21日
在for循环中包含delete _bar;
和forward_list.remove(_bar);
会在迭代器递增时导致运行时错误。
我选择将所有权控制权完全保留在Foo中,并使用这样的模板:
template<class T> T* AddBar()
{
Bar* object = new T();
Bars.push_front(object);
return object;
}
// Usage looks like...
Process* pid = foo.AddBar<MyBar>(); // adding a subclass of Bar
我使用指针作为PID——用于查找目的。我总是可以返回int
,以防止用户在不首先强制转换的情况下进行delete
ing。哦,对于参数,我可以执行AddBar(void* arguments)
简单地说,你不能。指针是指针。你首先应该避开他们。如果您选择使用它们,请创建一个文档策略,并对代码进行适当的审查。
在你的例子中,所有权的转移发生了(或者至少在设计的一半也很糟糕),你必须记录下来。必须仅使用使用特定方式创建的对象来调用函数&酒吧违反了这一规定,必须在审查中予以追究。
更改接口和实现以使用unique_ptr
。
虽然用户仍然可以将他们的堆栈指针封装在unique_ptr
中,但至少很明显,这种情况正在发生。
struct Foo {
typedef std::vector< std::unique_ptr<Bar> > bar_storage;
bar_storage bars;
Bar* AddBar( std::unique_ptr<Bar> );
void DeleteBar( Bar* bar );
};
void Foo::AddBar(std::unique_ptr<Bar> bar)
{
Bars.push_back(std::move(bar));
}
void Foo::DeleteBar(Bar* bar)
{
for (bar_storage::iterator index = Bars.begin(); index != Bars.end(); ++index)
{
if (bar == *index)
{
Bars.erase(index);
}
}
}
我所做的是将未定义的行为推送到调用站点,特别是:
Bar bar;
foo.AddBar(&bar); // does not compile
相反,呼叫者被迫:
foo.AddBar(std::unique_ptr<Bar>(&bar)); // user just did something really vulgar!
foo.DeleteBar(&bar); // Memory corruption on "delete _bar"
特别是,因为您的foo
表示Bar
的所有权,所以向Foo
添加Bar
只能由已经拥有Bar
的代码完成。将这种唯一所有权表示为std::unique_ptr<Bar>
,一直到创建,您有权删除的是unique_ptr
,而您没有删除的则是Bar*
。
相关文章:
- 从堆栈分配的原始指针构造智能指针
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 堆栈分配的类类型.为什么两个 ID 实例的地址相同?
- C++析构函数调用两次,堆栈分配的复合对象
- 了解通过引用传递取消引用指针时C++堆/堆栈分配
- C++,在对象内分配多个数据时,堆栈分配是否更有效? 在下面的程序中,类A_Heap的效率会更低吗?
- 何时在函数中声明堆栈分配变量?
- 使用 std::map 的递归堆栈分配如何工作?
- tcmalloc 与纯堆栈分配性能有多接近
- 安全分配堆栈分配的阵列
- C++ 中的黑白堆分配对象和堆栈分配对象的性能差异
- 跟踪(堆栈分配)对象
- 堆栈分配的确切时间
- 未初始化的值是由堆栈分配 - Qt - C++创建的
- 用于堆栈分配对象的C++虚拟析构函数内联
- C STD :: BAD_ALLOC来自堆栈分配
- 是使用COM创建的对象,将采用分配或堆栈分配的内存
- C++ 中针对大型的堆栈分配
- 堆栈分配的向量如何在 C++ 中扩展