C ++设置迭代器未到达Set的结尾

时间:2014-04-25 01:33:12

标签: c++ set stdset

我最近决定尝试将C ++解决方案用于最近结束的topcoder.com竞赛,作为学习该语言的一种方式(对C ++来说是新手)。但是,当通过std :: set对象的迭代没有成功到达集合中的所有元素(set.count>遍历的#个元素)时,我感到难过。我在StackExchange和其他地方经历过这种情况的其他人都徒劳无功。

细节

我已将代码发布到pastebin:http://pastebin.com/U7xQzDQg

我试图做的是一个天真的聚类算法。我确信有更好的方法来实现我想做的事情;但是在这个阶段我并不感兴趣(因为我的重点是学习语言及其特性)。我用位置对象表示笛卡尔网格中的方块,属性为“x”和“y”。使用迭代方法,我扫描整个网格,寻找相同颜色的对象,将它们分组到Cluster对象中。当算法完成时,将有一组聚类,每个聚类包括一组间隔不超过设定距离的位置对象。在算法期间的某个时刻,有必要合并彼此接近的集群;这是我开始遇到问题的地方。

如果您编译并运行在pastebin上发布的代码,您将看到如下消息:

TO MERGE:
Cluster of size 1: [1,1], 
Cluster of size 2: [0,1], [0,2], 
MERGED: 0x7fffb5e9b970Cluster of size 3: [0,1], [1,1], 

如果我的代码工作正常,最后一行应该显示的是:

MERGED: <Memory Address of Cluster>Cluster of size 3: [0,1], [1,1], [0,2],

尝试合并时会生成这些行(参见第54行);使用标准集迭代,由运算符强制转换方法生成的Cluster对象的字符串表示形式(参见第97行)。

显而易见的是,尽管该集合声称拥有正确数量的元素,但迭代整个集合并未达到所有元素。我认为对象超出范围并被破坏可能是一个问题;但这似乎并非如此,因为std :: set对象在将元素插入数据结构之前复制元素(并且在Position元素上使用析构函数进行测试)。

我真的很茫然,并且不想破解它...因为我认为这里有一些重要的东西。任何人都可以帮助我吗?

最佳, 马修

2 个答案:

答案 0 :(得分:1)

return output.c_str();

是未定义的行为,因为您的output字符串超出了范围,并且在函数返回时删除了基础字符数组。

您的operator const char* () const函数可能应该是

friend std::ostream& operator<<(std::ostream&, Cluster const&)

直接写入std::cout

的函数

请记住free任何你有calloc编辑的内容,或者更好的是,如果可以避免,最好还是不要在堆上分配内容。

答案 1 :(得分:1)

您的程序显示未定义的行为,因为operator<不会导致您的Position个对象strict weak ordering

bool operator< (Position other) const {
    return other.x - x + 100*(other.y - y);
}

您可以改用以下内容:

bool operator< (Position other) const {
    if (y < other.y) return true;
    if (y > other.y) return false;
    return x < other.x;
}