Why this program give out zero ?

Y

yuyang08

Hi, all

I wirte a small program to test some properties of map and vector. It
seems that the pointers I got can only support add opertion, and
cannot support substract operation. Is there anything wrong with my
program?

Thanks a lot!


#include <map>
#include <vector>
#include <iostream>

using namespace std;

typedef vector<int> IntVector;
typedef vector<int>::iterator IntVectorIterator;
typedef map<int, IntVectorIterator> IntMap;
typedef IntMap::iterator IntMapIterator;

int main()
{
IntVector ivec;
IntVectorIterator iit;
IntMap imap;

ivec.clear();
imap.clear();

iit = ivec.insert(ivec.begin(), 5 );
imap.insert( make_pair(5, iit) );

iit = ivec.insert(ivec.begin(), 19 );
imap.insert( make_pair(19, iit) );

iit = ivec.insert(ivec.begin(),22 );
imap.insert( make_pair(22, iit) );

IntMapIterator imit= imap.find(5);


cout<<"ivec.size() = "<<ivec.size()<<endl;
cout<< *(imit->second)<<endl;;
cout<< "&(*(imit->second))="<< &(*(imit->second))<<endl;

// expect 19, but got zero
cout<< "*(&(*(imit->second))-1)="<< *( &(*(imit->second)) - 1
)<<endl;

//expect 22, but get zero
cout<< "*(&(*(imit->second))-2)="<< *( &(*(imit->second)) - 2
)<<endl;

return 0;
}
 
V

Victor Bazarov

I wirte a small program to test some properties of map and vector. It
seems that the pointers I got can only support add opertion, and
cannot support substract operation. Is there anything wrong with my
program?

Yes. You seem to think that iterators remain OK all the time. That is
simply not true. std::vector is one of the most unreliable containers
in that respect. Its iterators get invalidated (become invalid) the most
of all. There are particular rules about that, and you can read about
them in books, but you can safely assume that any operation of inserting
or removing an element in/from a vector invalidates _all_ iterators.

There is no work-around, essentially. You shouldn't hold onto iterators
to elements of a vector.
Thanks a lot!


#include <map>
#include <vector>
#include <iostream>

using namespace std;

typedef vector<int> IntVector;
typedef vector<int>::iterator IntVectorIterator;
typedef map<int, IntVectorIterator> IntMap;
typedef IntMap::iterator IntMapIterator;

int main()
{
IntVector ivec;
IntVectorIterator iit;
IntMap imap;

ivec.clear();
imap.clear();

iit = ivec.insert(ivec.begin(), 5 );
imap.insert( make_pair(5, iit) );

iit = ivec.insert(ivec.begin(), 19 );

Right here the iterator stored in your 'imap' with the key 5 has already
been invalidated.
imap.insert( make_pair(19, iit) );

iit = ivec.insert(ivec.begin(),22 );
imap.insert( make_pair(22, iit) );

Now both iterators with keys 5 and 19 are invalid.
IntMapIterator imit= imap.find(5);

I am sure it will find the right element here. The only caveat is that
the second part of that element is not valid any longer.
cout<<"ivec.size() = "<<ivec.size()<<endl;
cout<< *(imit->second)<<endl;;
cout<< "&(*(imit->second))="<< &(*(imit->second))<<endl;

Boom!!! Undefined behaviour. You attempted to use the 'imit->second'
by dereferencing it (invoking operator* for it), which for an invalid
iterator is undefined.
// expect 19, but got zero
cout<< "*(&(*(imit->second))-1)="<< *( &(*(imit->second)) - 1
)<<endl;

//expect 22, but get zero
cout<< "*(&(*(imit->second))-2)="<< *( &(*(imit->second)) - 2
)<<endl;

return 0;
}

HTH

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top