如何在不因内存不足而导致应用程序崩溃的情况下擦除矢量元素?

Posted

技术标签:

【中文标题】如何在不因内存不足而导致应用程序崩溃的情况下擦除矢量元素?【英文标题】:How do I erase an element of vector without application crashing due to lack of memory? 【发布时间】:2015-09-09 14:30:55 【问题描述】:

所以这个问题很难用标题来解释,所以就这样吧:

在我的 32 位应用程序中,我有一个点云向量,例如大小为 4000。假设点云的每个元素中有 20 000 个点。

我希望能够根据我的情况删除点云。

问题是,我的 4000 个元素几乎已经达到了内存使用限制(例如,如果我有 4500 个元素,我的应用程序会崩溃)。

如果我在矢量大小为 4000 时删除点云,它会崩溃,如果它是较小的大小(比如说 2000 左右),它不会崩溃。

我的理论:擦除它时,它会在其他地方重新分配向量,但是当我接近内存限制时这样做,它会达到内存上限并使我的应用程序崩溃?

有没有办法确保向量保持在那个“位置”并且不会让我的应用程序崩溃或任何其他解决方案?

提前致谢!

【问题讨论】:

你这里有一个更深层次的问题。删除对象永远不会导致崩溃。我的猜测是您继续引用未分配的内存,但这只是在黑暗中拍摄。 你在遍历向量吗?从向量中删除某些元素后,迭代器无效。 @Logicrat OTOH,擦除矢量中间的元素将需要复制以下元素。根据存储在向量中的类型,这可能需要一些内存分配。因此,在某些情况下,删除某些内容可能会导致请求内存。 你的向量是 std::vector 吗? 它是点云(包含点)的 std::vector。我认为没有办法解决我的内存崩溃,所以我会以不同的方式解决问题,为每个点云设置一个布尔值是否为真或假,以确定我是否要保留它,一旦我进入我的保存功能我会忽略它们。 【参考方案1】:

我不确定是否要删除矢量元素,但我想建议您更改元素顺序而不是重新分配。 我认为重组向量的成本会低于重新分配新内存的成本,并且在向量的末尾,您可以用 NULL 标记空位置或持有 var 来表示向量的实际大小(在您的情况下,在删除点之后实际大小为 3999)。 这样您的分配只完成一次,您不再需要使用操作系统分配器。

【讨论】:

这是一种避免问题的方法,但并不能真正解决崩溃的原因。 我认为他\她提到了最大内存使用造成的迷恋,我认为没有办法克服它。即使我认为它会更广泛,然后重新组织向量。 是的,不幸的是,这将永远持续下去,而且我什至不确定这是否能解决内存问题......它可能会。我发布了我认为我会做的事情作为对初始帖子的评论,感谢您的建议!

以上是关于如何在不因内存不足而导致应用程序崩溃的情况下擦除矢量元素?的主要内容,如果未能解决你的问题,请参考以下文章

如果允许JVM在垃圾收集期间移动堆内存,那么垃圾收集如何不因移动指针而导致JNI爆炸?

Android 堆碎片化策略?

如何检测内存不足的情况?

如何实现 didReceiveMemoryWarning?

云帮手在windows下提示虚拟内存不足,如何解决?

如何避免由于内存不足导致的gcc崩溃