【问题标题】:Segmentation fault executing method分段错误执行方法
【发布时间】:2012-04-27 07:56:04
【问题描述】:

我编码的相关(我认为)行如下。 这意味着有一个集群列表。 其中一个,base,将吸收另一个(aborbed)。 aborbed 集群应该从list 中删除。

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

现在,更大的问题是我在方法 joinCluster() 的行 c->getPoints(); 中遇到了一个分段错误 我究竟做错了什么?我该怎么办?

我在 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();
};

【问题讨论】:

    标签: c++ pointers iterator


    【解决方案1】:
    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 持有无效地址。

    【讨论】:

    • 你说得对,我已经更正了++li 部分。关于你的第二段:当我从列表中删除一个元素时,它真的从内存中删除了吗?还是只是从列表中删除,但“单独”可用?
    • @Luis 标准容器按值存储元素。删除一个元素后,它就消失了,与之相关的所有迭代器、指针和引用都将失效。在调用 erase() 或复制元素之前,您必须进行“吸收”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多