views:

462

answers:

3

I have a map defined like this

std::map<some_key_type, std::string::iterator> mIteratorMap;

And a huge string named "mHugeString". Then I walk trough the string collecting iterators like this:

std::string::iterator It=mHugeString.begin();
std::string::iterator EndIt=mHugeString.end();
for(;It!=EndIt;++It){
  ...defining a key element...
  if(need_to_store_an_iterator)mIteratorMap[key_of_a_right_type]=It;
}

In the end I should recieve a map, where an iterator is associated with a some sort of key. But the iterator somehow looses itself when being paired with a key by "make_pair", unless it points to a place somewhere in the end of a string. It's hard to tell, but maybe last 256 bytes are fine.

So the question is not how to avoid loosing iterators, it was a stupid idea to store them anyways, but why trying to store an iterator in the begining of the string fails, and why the same with the iterators on the end works fine? What is the difference between them?

+3  A: 

I haven't tried it but I would have expected that, of course you can store iterator values as values in a map.

Do you know that if you change the contents of mHugeString then any iterators into it which you have previously stored are now invalid?

You might choose to store the index into the string, instead of the iterator.

ChrisW
Yes, and I did expect the same. Looks like something's wrong with an implementation of "make_pair".
akalenuk
+3  A: 

I am not sure why it should be problem. I wrote this code to check storage and retrieval of iterator which seems to work fine. [Note: I am not using make_pair as it should not be relevant, give try without using it though!]

#include <string>
#include <iostream>
#include <map>

enum UniqueKey {One, Two, Three};

typedef std::map<UniqueKey, std::string::iterator> UniqueKeyStringMap;

int main()
{
    UniqueKeyStringMap storage;

    std::string stringOne = "This is one string";

    std::string::iterator it = stringOne.begin() + 8; // "o"
    std::cout << " Iterator to store: " << std::string(it, it + 3) << std::endl;

    storage[UniqueKey::One] = it;   // Store iterator

    // Retrieve and print, string and map are valid

    UniqueKeyStringMap::iterator mapIter = storage.find(UniqueKey::One);
    if (mapIter != storage.end())
    {
        std::cout << " From storage: " << 
            std::string(mapIter->second, mapIter->second + 3) << std::endl;
    }
}

expected output: Iterator to store: one From storage: one

Ketan
I have no problem with a small string either. The issue occurs when trying to store an iterator far from the end of the string.
akalenuk
What do you mean by "far from the end" ? Are you using reverse iterator? Iterator are basically ptrs so should not have any limitation. Are you sure you are not corrupting your storage or something?How big your strings are?
Ketan
+1  A: 

It's fine, you can store iterators in the map. If you get some error, that is caused by something else. Note that if you modify your string, iterators pointing into your string will become invalid.

Please show us a complete, compilable code snippet that is rendered unusable, so we can analyze it.

Johannes Schaub - litb