C ++:指向另一个向量的对象的指针向量

时间:2016-02-05 13:23:46

标签: c++ pointers c++11 vector connected-components

我有两个类,类似于:

class A
{
public:
    B* ptr1;
}

class B
{
public:
    std::vector<A*> list;
}

在主要实施中,我做了类似的事情:

int main() {

// there are a lot more A objects than B objects, i.e. listOfA.size() >>> listOfB.size()
std::vector<A> listOfA;
std::vector<B> listOfB; 

while (//some loop)
{
    listOfB[jj].list.push_back( &(listofA[ii]) );
    listOfA[ii].ptr1 = &( listOfB[jj] );
}

} // int main end

基本上是这样的。许多A对象被分配给一个B对象,并且这些A对象作为指针存储在该指针向量中。此外,这些A对象中的每一个都获得指向它们所属的B对象的指针。对于上下文,我基本上使用运行长度编码(用于图像分割)进行连通分量算法,其中A类是线段,B类是图像中的最终对象。

因此,B类中向量的指针都指向存储在常规向量中的对象。当常规向量超出范围时,应删除这些对象,对吧?我已经读到类B中的指针向量通常需要编写一个手动析构函数,但我认为这不应该是这样的,我认为...

我问的原因当然是因为我的代码不断崩溃。我使用华硕Xtion Pro相机获取图像,然后在每张图像上执行算法。奇怪的是,每当我稍微晃动相机时程序就会崩溃。当相机静止或仅移动一点或慢时,没有任何反应。此外,当我使用不同的算法(也连接组件,但没有运行长度编码,也没有使用指针)时,无论我多少摇动相机,都不会崩溃。此外,在调试模式下(运行速度比发布模式慢得多),也没有任何崩溃。

我尝试在B类中为指针向量创建一个析构函数,但它导致&#34;块有效&#34;错误,所以我猜它删了两次。 我也尝试用c ++ 11 std :: shared_ptr替换每个指针,但这只会产生非常不规则的行为,当我摇动相机时代码仍然崩溃。

我基本上只是想知道在内存泄漏和指针处理方面,上面显示的代码似乎没问题,或者代码中是否存在可能导致崩溃的错误。

编辑(已解决):解决方案(请参阅接受的答案)是确保向量&#39; listOfB&#39;没有在运行时调整大小,例如使用&#39; reserve()&#39;为它预留足够的空间。这样做之后,一切正常!显然它有效,因为如果向量&#39; listOfB&#39;调整大小(通过push_back()),其中B实例的内部内存地址也会发生变化,导致A实例(指向B实例)中的指针现在指向错误的地址 - 从而导致出现问题,这导致了崩溃。

关于相机抖动,显然,摇动相机会导致图像非常模糊,需要分割大量元素,从而增加了对象的数量(即,导致listOfB所需的更大尺寸)。所以,神秘解决了!非常感谢! : - )

2 个答案:

答案 0 :(得分:2)

我认为设计已被打破。 listofB将增长(你执行push_backs)并重新分配其内部数据数组,使存储在A实例的ptrs中的所有地址无效。通常的算法会将数据大小增加2倍,这可以解释如果没有太多数据到达,你会好一段时间。此外,只要旧数据的内存仍然在程序的地址空间中(特别是如果它在同一个内存页面上,例如因为新数据也适合它),程序可能不会崩溃访问它只是检索旧数据。

更具建设性的说明:如果您事先知道最大元素,那么您的解决方案将会有效,这可能很难(想想明年你会得到一台4k相机;-))。顺便说一下,你可以采用一个简单的静态数组。

也许您也可以使用std::map来存储A对象而不是简单的向量listofA。每个A对象都需要某种类型的唯一ID(在最简单的情况下,A中的静态计数器)用作映射中的键。 Bs会存储密钥,而不是As的地址。

答案 1 :(得分:0)

假设您在如何构建网络时没有犯错,那么您应该没问题。你必须发布更多的代码来评估。在更改其中一个之后,您也无法使用任何向量,因为如果它们重新分配其成员,则指向它们的所有指针都将失效。但是使用原始指针托管对象是构建网络的正确方法。

通过托管对象我指的是保证其生命周期比网络更长并且其内存将自动释放的对象。因此它们应该是由某种智能指针管理的容器或对象的元素。

然而,听起来你有硬件问题。