Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > std::map<int,std::set<std::string> > Wrong? (Segmentation fault.)

Reply
Thread Tools

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

 
 
Peter Jansson
Guest
Posts: n/a
 
      03-14-2005
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/
 
Reply With Quote
 
 
 
 
Ivan Vecerina
Guest
Posts: n/a
 
      03-14-2005
"Peter Jansson" <(E-Mail Removed)> wrote in message
news(E-Mail Removed) hell.org...
> 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<int,set<string> > repeatedly...

> 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
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form


 
Reply With Quote
 
 
 
 
Kristo
Guest
Posts: n/a
 
      03-14-2005
On 3/14/2005 4:33 AM, Ivan Vecerina wrote:
> "Peter Jansson" <(E-Mail Removed)> wrote in message
> news(E-Mail Removed) hell.org...
>
>>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
 
Reply With Quote
 
Jeff Schwab
Guest
Posts: n/a
 
      03-15-2005
Kristo wrote:
> On 3/14/2005 4:33 AM, Ivan Vecerina wrote:
>
>> "Peter Jansson" <(E-Mail Removed)> wrote in message
>> news(E-Mail Removed) hell.org...
>>
>>> 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)


No, in this case a std::set<std::string>. Look carefully at the
declaration of k.

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

 
Reply With Quote
 
Peter Jansson
Guest
Posts: n/a
 
      03-15-2005

On Mon, 14 Mar 2005, Ivan Vecerina wrote:

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


Yes, that is what I meant.

>> 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;
>> }

>
> 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::st ring> > 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/
 
Reply With Quote
 
Ivan Vecerina
Guest
Posts: n/a
 
      03-17-2005
"Peter Jansson" <(E-Mail Removed)> wrote in message
news(E-Mail Removed) ell.org...
> On Mon, 14 Mar 2005, Ivan Vecerina wrote:
>> 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.

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
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments