2013-01-14 68 views
0

可以说我已经分配了一些内存,并填充了一组相同类型的对象,我们称之为这些组件。C++从内存中删除对象

说这些组件中的一个需要被删除,这样做的好方法是什么,这样组件创建的“洞”可以通过循环遍历一组对象来测试和跳过?

倒数也应该是真的,我希望能够测试一个洞,以便在空间中存储新组件。

我想menclear &检查0 ...

+7

也许使用普通的容器会做得一样好,让你的生活更容易?或者,如果有理由需要这个特定的设置,到目前为止您尝试了什么? – aschepler

+2

当您询问'NULL'和'0'之间的区别时(真的应该在单独的问题中提问),请不要忘记C++ 11 ['nullptr'](http://en.wikipedia。组织/维基/ C++ 11#Null_pointer_constant)。 –

+3

“可以说我已经分配了”或者可能向我们展示您正在使用的一些代码?这是一个编码网站。 – GManNickG

回答

3

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; }); 
+0

阅读文档解释boost ::可选暴露了这个问题的细节。这实际上是解决这个问题的非常好的解决方案。 –

+0

优秀的示例代码。 – GManNickG

0

简短的回答是这取决于你如何存储在memmory。

例如,ansi标准建议向量连续分配。

如果您可以预测对象的大小,则可以使用size_of和addressing等函数来预测内存中的位置。

祝你好运。

0

至少有两种解决方案:

1)与一些标志标记孔,然后跳过它处理时。好处:'删除'非常快(只设置一个标志)。如果对象不是那么小,即使添加一个“bool alive”标志也不会那么难。

2)在池的末端移动一个洞,并用一些'alive'对象替换它。

这个问题与存储和处理粒子系统有关,你可以在那里找到一些建议。

+0

我考虑将最后一个元素移动到“洞”中,但这样做意味着要跟踪指向每个元素的指针。为了简单和速度的原因,我想避免移动元素。如果某个字节写入对象的第一个字节会怎么样? –

+0

是的,在元素之前(或之后)写单个字节也是有帮助的。请注意,您具有相同的对象,大小相同,因此在整个对象数组上“跳跃”很容易。但为了提高效率,你应该有一些漏洞列表。但是,这仍然是内存管理员的工作方式。 – fen

0

如果无法将“活”组件向上移动或对其重新排序以使序列中间没有空洞,那么最好的选择是如果给组件对象一个“删除的”标志/状态,可以通过成员函数进行测试。
这样一个“已删除”状态确实是而不是导致从内存中移除该对象(这在大块的中间是不可能的),但它确实能够将该点标记为未被使用为一个组件。

0

当你说你已经“分配了一些内存”时,你可能正在讨论一个数组。数组非常棒,因为它们几乎没有开销,并且索引访问速度非常快。但是关于数组的坏处是它们对于调整大小不是很友好。当您移除中间的元素时,所有后续元素必须移回一个位置。

但幸运的是,您可以使用其他数据结构,例如linked listbinary tree,它们允许快速删除元素。 C++甚至在容器类std::liststd::set中实现了这些。

当您事先不知道需要多少元素时,列表非常棒,因为它可以动态缩小和增长,而不会在删除或添加任何元素时浪费任何内存。此外,添加和删除元素的速度非常快,无论您是在开始,结束还是在中间的某个位置插入元素。

一组很适合快速查找。当你有一个对象,并且你想知道它是否已经在这个集合中时,检查它是非常快的。一套也会自动丢弃在许多情况下非常有用的重复项(当您需要重复项时,有std::multiset)。就像一个列表一样,它动态地适应,但添加新对象的速度并不像列表中的那么快(但不像数组中的那么昂贵)。

+0

我正在谈论一个数组,我不喜欢链接列表,因为它们将内存碎片化,并且要求缓存未命中。 –

+1

你知道内存碎片和缓存未命中,但你不知道如何正确使用数组? – Philipp

+0

@Philipp:由于标准数组不支持他请求的功能,我很好奇为什么你说他不知道如何正确使用数组? –

0

两个建议:

1)您可以使用一个Linked List来存储您的组件,然后不用担心孔。

或者,如果你需要这些孔:

2)您可以用指针包装你的组件为对象的组件,像这样:

class ComponentWrap : public 
{ 
    Component component; 
} 

,并使用ComponentWrap.component == null发现该组件是删除。

异常方式:

3)把你的代码在一个try catch块的情况下,你打一个空指针错误。

+0

随着新的C++,你甚至可以去Warp 11. –

+0

修复它:P对不起 – Vladp