I need to remove vector elements based on timeval

76 views Asked by At

I have a queue of audio elements for each frame of a movie. I want to remove them from last seen to first seen up to a certain max number of elements. I use timeval to determine the time value. I have problems with the iterators due to calling erase on the elements.

I tried creating a std::multimap to store all the iterators based on the timeval key. Then I stored all the iterators on a vector based on max_frames to remove. I then sorted the vector of iterators from greater to less. Then erased all iterators.

// C++
void CMedia::timed_limit_audio_store(const int64_t frame)
{
    unsigned max_frames = max_audio_frames();


    struct customMore {
        inline bool operator()( const timeval& a,
                                const timeval& b ) const
        {
          return (((a).tv_sec == (b).tv_sec) ?
                  ((a).tv_usec > (b).tv_usec) : 
                   (a).tv_sec > (b).tv_sec)));
        }
    };

    typedef std::multimap< timeval, audio_cache_t::iterator,
                           customMore > TimedSeqMap;
    TimedSeqMap tmp;
    {
        audio_cache_t::iterator  it = _audio.begin();
        audio_cache_t::iterator end = _audio.end();
        for ( ; it != end; ++it )
        {
            if ( (*it)->frame() - max_frames < frame )
                tmp.insert( std::make_pair( (*it)->ptime(), it ) );
        }
    }



    unsigned count = 0;
    TimedSeqMap::iterator it = tmp.begin();
    typedef std::vector< audio_cache_t::iterator > IteratorList;
    IteratorList iters;
    for ( ; it != tmp.end(); ++it )
    {
        ++count;
        if ( count > max_frames )
        {
            // Store this iterator to remove it later
            iters.push_back( it->second );
        }
    }

    IteratorList::iterator i = iters.begin();
    IteratorList::iterator e = iters.end();

    // We sort the iterators from bigger to smaller to avoid erase
    // trashing our iterator.  However, this is not working properly.
    std::sort( i, e, std::greater<audio_cache_t::iterator>() );

    i = iters.begin();
    e = iters.end();
    for ( ; i != e; ++i )
    {
        _audio.erase( *i );
    }
}

The expected result would be that the vector's elements are removed based on the timeval of the audio elements. The actual errors are memory trashing and sometimes crashes.

0

There are 0 answers