2012-04-15 47 views
1

我的编码的相关(我认为)行如下。 是什么意思是有一个集群列表。 其中之一,base,将吸收另一个(aborbed)。 应该从list中删除aborbed群集。分割错误执行方法

我遇到的第一个问题是在while周期关闭后,我需要在baseabsorbed集群中执行其他操作。 从我的搜索中,我找到了= &(*li)的东西。我的理解是我得到一个指向li元素地址的指针,虽然我不能这样做absorbed = li,因为一个是迭代器,另一个是(简单的?)ponter。我会很感激这方面的一些解释。

现在,更大的问题是,我在方法joinCluster() 的线c->getPoints();中发现了sementation故障我做错了什么?我该怎么做为什么?

我在Linux x86_64中使用g ++(GCC)4.5.2。

Cluster * base; 
Cluster * absorbed; 

list<Cluster>::iterator li = clusters.begin(); 
while (li != clusters.end()) { 
    if (li->getId() == p2) { 
     absorbed = &(*li); 
     li = clusters.erase(li); 
    } else if (li->getId() == p1) { 
     base = &(*li); 
    } 
++li; 
} 

base->joinCluster(absorbed); 


void Cluster::joinCluster(Cluster * c) 
{ 
    set<unsigned int> pts = c->getPoints(); 
} 

set<unsigned int> Cluster::getPoints() 
{ 
return points; 
} 

class Cluster { 
    private: 
    std::set<unsigned int> points; 
    public: 
    std::set<unsigned int> getPoints(); 
}; 

回答

4
list<Cluster>::iterator li = clusters.begin(); 
while (li != clusters.end()) { 
    if (li->getId() == p2) { 
     absorbed = &(*li); 
     li = clusters.erase(li); 
    } else if (li->getId() == p1) { 
     base = &(*li); 
    } 
++li; // <---- Don't increment when you already deleted. 
} 

当你删除然后在列表中最后一个元素,li变得cluster.end()。然后你再次增加它,并繁荣,你超出了界限。 ++li应该在else区块中。

另请注意,当您从容器中清除li时,absorbed包含无效的地址。

+0

你说得对,我已经纠正了'++ li'部分。关于你的第二段:当我从列表中删除一个元素时,它真的从内存中删除了吗?或者只是从列表中删除,但可以“单独”? – Luis 2012-04-16 09:06:54

+0

@Luis标准容器按值存储元素。删除一个元素后,它就消失了,所有与它相关的迭代器,指针和引用都将失效。在调用'erase()'或复制元素的副本之前,您必须先执行“吸收”。 – jrok 2012-04-16 10:48:56