mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-03 16:47:47 +08:00
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:
co-authored by
Claude Opus 5.5
matlabbe
parent
8035be52ff
commit
5c9cfa98fe
@@ -2029,7 +2029,7 @@ void DatabaseViewer::updateIds()
|
||||
envSensors_.insert(std::make_pair(ids_[i], sensors));
|
||||
if(w>=0)
|
||||
{
|
||||
for(std::multimap<int, Link>::iterator iter=links.find(ids_[i]); iter!=links.end() && iter->first==ids_[i]; ++iter)
|
||||
for(std::multimap<int, Link>::iterator iter=links.lower_bound(ids_[i]); iter!=links.end() && iter->first==ids_[i]; ++iter)
|
||||
{
|
||||
// Make compatible with old databases, when "weight=-1" was not yet introduced to identify ignored nodes
|
||||
if(iter->second.type() == Link::kNeighbor || iter->second.type() == Link::kNeighborMerged)
|
||||
@@ -2070,7 +2070,7 @@ void DatabaseViewer::updateIds()
|
||||
previousPose=p;
|
||||
|
||||
//links
|
||||
for(std::multimap<int, Link>::iterator jter=links.find(ids_[i]); jter!=links.end() && jter->first == ids_[i]; ++jter)
|
||||
for(std::multimap<int, Link>::iterator jter=links.lower_bound(ids_[i]); jter!=links.end() && jter->first == ids_[i]; ++jter)
|
||||
{
|
||||
if(jter->second.type() == Link::kNeighborMerged)
|
||||
{
|
||||
@@ -4852,7 +4852,7 @@ void DatabaseViewer::updateCovariances(const QList<Link> & links)
|
||||
infMatrix.clone(),
|
||||
currentLink.userDataCompressed());
|
||||
bool updated = false;
|
||||
std::multimap<int, Link>::iterator iter = linksRefined_.find(currentLink.from());
|
||||
std::multimap<int, Link>::iterator iter = linksRefined_.lower_bound(currentLink.from());
|
||||
while(iter != linksRefined_.end() && iter->first == currentLink.from())
|
||||
{
|
||||
if(iter->second.to() == currentLink.to() &&
|
||||
@@ -6681,7 +6681,7 @@ void DatabaseViewer::editConstraint()
|
||||
{
|
||||
cv::Mat covariance = dialog.getCovariance();
|
||||
Link newLink(link.from(), link.to(), link.type(), dialog.getTransform(), covariance.inv());
|
||||
std::multimap<int, Link>::iterator iter = linksRefined_.find(link.from());
|
||||
std::multimap<int, Link>::iterator iter = linksRefined_.lower_bound(link.from());
|
||||
while(iter != linksRefined_.end() && iter->first == link.from())
|
||||
{
|
||||
if(iter->second.to() == link.to() &&
|
||||
@@ -9462,7 +9462,7 @@ void DatabaseViewer::refineConstraint(int from, int to, Registration * reg, Regi
|
||||
Link newLink(currentLink.from(), currentLink.to(), currentLink.type(), transform, info.covariance.inv(), currentLink.userDataCompressed());
|
||||
|
||||
bool updated = false;
|
||||
std::multimap<int, Link>::iterator iter = linksRefined_.find(currentLink.from());
|
||||
std::multimap<int, Link>::iterator iter = linksRefined_.lower_bound(currentLink.from());
|
||||
while(iter != linksRefined_.end() && iter->first == currentLink.from())
|
||||
{
|
||||
if(iter->second.to() == currentLink.to() &&
|
||||
|
||||
Reference in New Issue
Block a user