Use lower_bound() before iterating multimap entries of a key (#1776)

Several places look up a multimap with find(key) and then iterate while
iter->first == key, assuming find() returns the first element with that key.
The standard does not guarantee this, and recent libc++ (Apple clang 21 /
libc++ 2200) returns an arbitrary matching element. graph::findLink() then
misses existing links and Optimizer::getConnectedGraph() aborts with
"Condition (kter!=linksIn.end()) not met!" on graphs with loop closures or
multiple sessions (rtabmap-export --opt 0, rtabmap-reprocess, etc.).

Replace find() with lower_bound() at those sites and add a regression test.

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
Co-authored-by: matlabbe <[email protected]>
This commit is contained in:
Nathan Totten
2026-09-27 18:37:17 -07:00
committed by GitHub
co-authored by Claude Opus 5.5 matlabbe
parent 8035be52ff
commit 5c9cfa98fe
6 changed files with 46 additions and 23 deletions
+2 -2
View File
@@ -144,7 +144,7 @@ bool Signature::hasLink(int idTo, Link::Type type) const
}
else
{
for(std::multimap<int, Link>::const_iterator iter=_links.find(idTo); iter!=_links.end() && iter->first == idTo; ++iter)
for(std::multimap<int, Link>::const_iterator iter=_links.lower_bound(idTo); iter!=_links.end() && iter->first == idTo; ++iter)
{
if(type == iter->second.type())
{
@@ -157,7 +157,7 @@ bool Signature::hasLink(int idTo, Link::Type type) const
void Signature::changeLinkIds(int idFrom, int idTo)
{
std::multimap<int, Link>::iterator iter = _links.find(idFrom);
std::multimap<int, Link>::iterator iter = _links.lower_bound(idFrom);
while(iter != _links.end() && iter->first == idFrom)
{
Link link = iter->second;