mbuffier
mbuffier

Reputation: 11

BAD_ACCES iterator on map c++

I'm trying to implement a function using a map in a map like that :

typedef std::map<int, float> inner_map;
typedef std::map<int, inner_map> outer_map;

I'm filling the map this way. The idea is the first map contains a int key and an other map which contains another key and a float. If the pair I obtain is known, I increment the value otherwise I fill the map.

for (int y = 2; y < imgSize.y - 2; y++){
    for (int x = 2; x < imgSize.x - 2; x++) {
        thisPos = x + y*imgSize.x ;

        {SOME CODE}

        lj = labelMap[thisPos] ;

        if (condition) {
            // get the 2 label 
            li = pro_label_mod[thisPos] ; 

            // look if it lj is in the map 
            is_lj = pi_matrix.count(lj) ;

            // this lj has already been observed 
            if (is_lj == 1) {
                is_li = pi_matrix[lj].count(li);

                // this pair is known -> I increment 
                if (is_li==1) {
                    pi_matrix[lj][li] +=  1.0f ;
                }
                else {
                     pi_matrix.at(lj).insert(pi_matrix[lj].end(), std::make_pair(li, 1.0f)) ;
                }
            }
            else {
                inner_map inter ; inter.insert(std::make_pair(li, 1.0f)) ;
                pi_matrix.emplace(lj, inter) ;
            }
        }
        numb_lj[lj] += 1.0f ;
    }
}

And then, I would like to iterate throught the map in my code. I did that with iterators such as :

std::vector<std::pair<int,float> > max_pi(size_lj) ;

float maxValue, thisValue ; int label_max ; 

for (outer_map::iterator it_lj = pi_matrix.begin(), it_lj_end = pi_matrix.end(); it_lj != it_lj_end; ++it_lj) {
    maxValue = 0.0f ;
    label_max = 0 ;

    inner_map &innerMap = it_lj->second;

    for(inner_map::iterator it_li = innerMap.begin(), it_li_end = innerMap.end(); it_li != it_li_end; ++it_li) {
        thisValue = it_li->second / numb_lj[it_lj->first] ;

        if (thisValue >= maxValue) {
            maxValue = thisValue ;
            label_max = it_li->first ;
        }
    }

    max_pi[it_lj->first] = std::make_pair(label_max, maxValue) ;
    i+=1;
}

However, i'm getting a segmentation fault at the lines of the for loop (either the first one or the second one). BUT ! Not every time. I'm calling this function at each frame and I can have 5 calls without a BAD_ACCESS and suddenly, it crashes.. Sometimes after the first call and then the 10th.

I really can't see why and how to solve it..

Thank you in advance for any clues/comments which could be helpful !

Upvotes: 1

Views: 62

Answers (1)

Walter
Walter

Reputation: 45424

It appears that your design of a nested map is causing all sorts of unnecessary complications. More natural appears a single map with a pair<int,int> as key:

using key_type = std::pair<int,int>;
using map_type = std::map<key_type,float>;

void add_to_map(map_type&map, key_type const&key)
{
    map[key] += 1.f;   // also works as desired if map.count(key)==0
}

// find key and value of first element with maximum value
map_type::value_type find_max(map_type const&map)
{
    auto max = map.begin();
    for(auto it=max; it!=map.end(); ++it)
        if(it.second > max.second)
            max = it;
    return *max;
}

no need to juggle with map::count or map::iterator.

Upvotes: 2

Related Questions