可以说我已经分配了一些内存,并填充了一组相同类型的对象,我们称之为这些组件。C++从内存中删除对象
说这些组件中的一个需要被删除,这样做的好方法是什么,这样组件创建的“洞”可以通过循环遍历一组对象来测试和跳过?
倒数也应该是真的,我希望能够测试一个洞,以便在空间中存储新组件。
我想menclear &检查0 ...
可以说我已经分配了一些内存,并填充了一组相同类型的对象,我们称之为这些组件。C++从内存中删除对象
说这些组件中的一个需要被删除,这样做的好方法是什么,这样组件创建的“洞”可以通过循环遍历一组对象来测试和跳过?
倒数也应该是真的,我希望能够测试一个洞,以便在空间中存储新组件。
我想menclear &检查0 ...
boost::optional<component>
似乎完全适合您的需求。把它们放在你的存储器里,无论发生什么。例如,与std::vector
// initialize the vector with 100 non-components
std::vector<boost::optional<component>> components(100);
// adding a component at position 15
components[15].reset(component(x,y,z));
// deleting a component at position 82
componetnts[82].reset()
// looping through and checking for existence
for (auto& opt : components)
{
if (opt) // component exists
{
operate_on_component(*opt);
}
else // component does not exist
{
// whatever
}
}
// move components to the front, non-components to the back
std::parition(components.begin(), components.end(),
[](boost::optional<component> const& opt) -> bool { return opt; });
阅读文档解释boost ::可选暴露了这个问题的细节。这实际上是解决这个问题的非常好的解决方案。 –
优秀的示例代码。 – GManNickG
简短的回答是这取决于你如何存储在memmory。
例如,ansi标准建议向量连续分配。
如果您可以预测对象的大小,则可以使用size_of和addressing等函数来预测内存中的位置。
祝你好运。
至少有两种解决方案:
1)与一些标志标记孔,然后跳过它处理时。好处:'删除'非常快(只设置一个标志)。如果对象不是那么小,即使添加一个“bool alive”标志也不会那么难。
2)在池的末端移动一个洞,并用一些'alive'对象替换它。
这个问题与存储和处理粒子系统有关,你可以在那里找到一些建议。
我考虑将最后一个元素移动到“洞”中,但这样做意味着要跟踪指向每个元素的指针。为了简单和速度的原因,我想避免移动元素。如果某个字节写入对象的第一个字节会怎么样? –
是的,在元素之前(或之后)写单个字节也是有帮助的。请注意,您具有相同的对象,大小相同,因此在整个对象数组上“跳跃”很容易。但为了提高效率,你应该有一些漏洞列表。但是,这仍然是内存管理员的工作方式。 – fen
如果无法将“活”组件向上移动或对其重新排序以使序列中间没有空洞,那么最好的选择是如果给组件对象一个“删除的”标志/状态,可以通过成员函数进行测试。
这样一个“已删除”状态确实是而不是导致从内存中移除该对象(这在大块的中间是不可能的),但它确实能够将该点标记为未被使用为一个组件。
当你说你已经“分配了一些内存”时,你可能正在讨论一个数组。数组非常棒,因为它们几乎没有开销,并且索引访问速度非常快。但是关于数组的坏处是它们对于调整大小不是很友好。当您移除中间的元素时,所有后续元素必须移回一个位置。
但幸运的是,您可以使用其他数据结构,例如linked list或binary tree,它们允许快速删除元素。 C++甚至在容器类std::list和std::set中实现了这些。
当您事先不知道需要多少元素时,列表非常棒,因为它可以动态缩小和增长,而不会在删除或添加任何元素时浪费任何内存。此外,添加和删除元素的速度非常快,无论您是在开始,结束还是在中间的某个位置插入元素。
一组很适合快速查找。当你有一个对象,并且你想知道它是否已经在这个集合中时,检查它是非常快的。一套也会自动丢弃在许多情况下非常有用的重复项(当您需要重复项时,有std::multiset)。就像一个列表一样,它动态地适应,但添加新对象的速度并不像列表中的那么快(但不像数组中的那么昂贵)。
我正在谈论一个数组,我不喜欢链接列表,因为它们将内存碎片化,并且要求缓存未命中。 –
你知道内存碎片和缓存未命中,但你不知道如何正确使用数组? – Philipp
@Philipp:由于标准数组不支持他请求的功能,我很好奇为什么你说他不知道如何正确使用数组? –
两个建议:
1)您可以使用一个Linked List来存储您的组件,然后不用担心孔。
或者,如果你需要这些孔:
2)您可以用指针包装你的组件为对象的组件,像这样:
class ComponentWrap : public
{
Component component;
}
,并使用ComponentWrap.component == null
发现该组件是删除。
异常方式:
3)把你的代码在一个try catch块的情况下,你打一个空指针错误。
随着新的C++,你甚至可以去Warp 11. –
修复它:P对不起 – Vladp
也许使用普通的容器会做得一样好,让你的生活更容易?或者,如果有理由需要这个特定的设置,到目前为止您尝试了什么? – aschepler
当您询问'NULL'和'0'之间的区别时(真的应该在单独的问题中提问),请不要忘记C++ 11 ['nullptr'](http://en.wikipedia。组织/维基/ C++ 11#Null_pointer_constant)。 –
“可以说我已经分配了”或者可能向我们展示您正在使用的一些代码?这是一个编码网站。 – GManNickG