std::map<int,std::set<std::string> > Wrong? (Segmentation fault.)

P

Peter Jansson

Hello,

I have the following code:

std::map<int,std::set<std::string> > k;
k[0]="1234567890";
k[1]="2345678901";
//...
std::set<std::string> myMethod(std::map<int,std::set<std::string> > k)
throw(std::runtime_error)
{
std::map<int,std::set<std::string> >::const_iterator i;
i=k.find(0);
if(i==k.end())
throw std::runtime_error("No zero in k.");
return i->second;
}

Compilation of this code goes well, but I have the following problem while
executing this in my implementation: "Segmentation fault". I have
pin-pointed the problem to be the last return statement. When I ignore
using find(int) and instead loops over the map with the following code,
everyting goes fine.

std::set<std::string> strings;
for(i=k.begin();i!=k.end();i++)
{
if(k->first==0)
strings=k->second;
}
return strings;

Anybody know what is going on here?

Regards,
Peter Jansson
http://www.jansson.net/
 
I

Ivan Vecerina

Peter Jansson said:
Hello,

I have the following code:

std::map<int,std::set<std::string> > k;
k[0]="1234567890";
k[1]="2345678901";
The above two lines are incorrect.
Maybe you meant:
k[0].insert("1234567890");
k[1].insert("2345678901");
//...
std::set<std::string> myMethod(std::map<int,std::set<std::string> > k)

NB: you probably want to pass the k parameter by const reference:
std::set<std::string> myMethod(std::map<int,std::set<std::string> > const&
k)
BTW: a typedef of two would probably make sense instead of writing
map said:
throw(std::runtime_error)
{
std::map<int,std::set<std::string> >::const_iterator i;
i=k.find(0);
if(i==k.end())
throw std::runtime_error("No zero in k.");
return i->second;
}

The above code seems ok, and I don't see a problem in it.
Maybe you could post a complete working sample?


Regards,
Ivan
 
K

Kristo

Hello,

I have the following code:

std::map<int,std::set<std::string> > k;
k[0]="1234567890";
k[1]="2345678901";

The above two lines are incorrect.
Maybe you meant:
k[0].insert("1234567890");
k[1].insert("2345678901");

What's wrong with them? If an object with key x doesn't exist,
operator[] will create a default object (in this case a string) to which
a value (e.g., "1234567890") can be safely assigned.

Kristo
 
J

Jeff Schwab

Kristo said:
Hello,

I have the following code:

std::map<int,std::set<std::string> > k;
k[0]="1234567890";
k[1]="2345678901";


The above two lines are incorrect.
Maybe you meant:
k[0].insert("1234567890");
k[1].insert("2345678901");


What's wrong with them? If an object with key x doesn't exist,
operator[] will create a default object (in this case a string)

to which
a value (e.g., "1234567890") can be safely assigned.

Kristo
 
P

Peter Jansson

The above two lines are incorrect.
Maybe you meant:
k[0].insert("1234567890");
k[1].insert("2345678901");

Yes, that is what I meant.
The above code seems ok, and I don't see a problem in it.
Maybe you could post a complete working sample?

Well, the non-working code is the myMethod method above (non-working since
it fails while executing, it compiles fine). Below, is the code that
works.

std::set<std::string> myMethod_which_works(std::map<int,std::set<std::string> > k)
throw(std::runtime_error)
{
std::map<int,std::set<std::string> >::const_iterator i;
std::set<std::string> strings;
bool haveNotFoundZero=true;
for(i=k.begin();i!=k.end() && haveNotFoundZero;k++)
{
if(i->first==0)
{
haveNotFoundZero=false;
strings=i->second;
}
}
if(haveNotFoundZero)
throw std::runtime_error("No zero in k.");
return strings;
}

I thought the method find should be more transparent and perhaps even
optimized for sorted maps but it did not work as already mentioned. I
would be grateful for any suggestion/hint on what is wrong.

Regards,
Peter Jansson
http://www.jansson.net/
 
I

Ivan Vecerina

Peter Jansson said:
Well, the non-working code is the myMethod method above (non-working since
it fails while executing, it compiles fine). Below, is the code that
works.
Again, your usage of the map::find member function seemed correct,
but a problem somewhere else in your code could not be excluded.
And as requested above, *you* should post a minimum code sample
that compiles and reproduces the problem you see.
Something like:

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

std::set<std::string>
myMethod(std::map<int,std::set<std::string> > const& k)
throw(std::runtime_error)
{
std::map<int,std::set<std::string> >::const_iterator i = k.find(0);
if(i==k.end())
throw std::runtime_error("No zero in k.");
return i->second;
}

int main()
{
std::map<int,std::set<std::string> > k;
k[0].insert("1234567890");
k[1].insert("2345678901");

std::set<std::string> set = myMethod(k); // does not throw
std::cout << *set.begin(); // prints "1234567890"
}
I thought the method find should be more transparent and perhaps even
optimized for sorted maps but it did not work as already mentioned.
map::find is transparent and optimized, and does work.
You shouldn't persuade yourself otherwise before writing a complete
minimum sample that compiles and illustrates the issue you observe.
I would be grateful for any suggestion/hint on what is wrong.
The above code shall work, and does on the platform I use.
If it fails on your system, this would be a bug in the implementation
you use, and you should seek support from your vendor or a platform-
specific forum (and use the code sample as a bug report).


Ivan
 

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,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top