why is this map crashing?

M

M

Below where you see ____THIS LINE

if that 80 is 32 then it works but anything over it blows up.

where am I wrong?

thanks


#include <bitset>
#include <map>
#include <iostream>

#pragma warning(disable:4786)
using namespace std;


typedef bitset<80> myBitSet;
struct eqmySet
{
bool operator()(const myBitSet& s1, const myBitSet& s2) const
{
return s1.to_ulong() < s2.to_ulong();
}

};

string ShowBitSet(myBitSet bs)
{
string s;

for(unsigned i = 0; i < bs.size(); i++)
{
if(bs.test(i))
{
s += "1";
}
else
s += "0";
}

return s;
}

typedef map<myBitSet, int, eqmySet> key_hash_t;

int main(int argc, char* argv[])
{
key_hash_t ht;

for(int j = 0; j < 3; j++)
{
myBitSet kb;

for(int i=0; i < 80; i++) <<<<<< ____THIS LINE
kb.set(i);

ht[kb]++;

}

key_hash_t::iterator p;

for(p = ht.begin(); p != ht.end(); ++p)
cout << ShowBitSet(p->first) << " : " << p->second << endl;


return 0;
}
 
M

Me

M said:
Below where you see ____THIS LINE

if that 80 is 32 then it works but anything over it blows up.

where am I wrong?
*snip*

typedef bitset<80> myBitSet;
struct eqmySet
{
bool operator()(const myBitSet& s1, const myBitSet& s2) const
{
return s1.to_ulong() < s2.to_ulong();

Right here
}

}; *snip*

typedef map<myBitSet, int, eqmySet> key_hash_t;
*snip*

myBitSet kb;

for(int i=0; i < 80; i++) <<<<<< ____THIS LINE
kb.set(i);

ht[kb]++;

Judging from the pragma you used in the original code, I'm guessing
you're on windows. unsigned longs on that platform are 32 bits so this
just uses the lower 32 bits of the bitset as the key. Since bitset
doesn't have relational operators you'll have to manually scan the bits
for this to work properly. That's a pretty lame solution, so I highly
suggest you take a look at Rob Williscroft's unsigned_int instead of
using bitset:

http://www.victim-prime.dsl.pipex.com/
 
M

M

Me said:
M said:
Below where you see ____THIS LINE

if that 80 is 32 then it works but anything over it blows up.

where am I wrong?
*snip*

typedef bitset<80> myBitSet;
struct eqmySet
{
bool operator()(const myBitSet& s1, const myBitSet& s2) const
{
return s1.to_ulong() < s2.to_ulong();

Right here
}

}; *snip*

typedef map<myBitSet, int, eqmySet> key_hash_t;
*snip*

myBitSet kb;

for(int i=0; i < 80; i++) <<<<<< ____THIS LINE
kb.set(i);

ht[kb]++;

Judging from the pragma you used in the original code, I'm guessing
you're on windows. unsigned longs on that platform are 32 bits so this
just uses the lower 32 bits of the bitset as the key. Since bitset
doesn't have relational operators you'll have to manually scan the bits
for this to work properly. That's a pretty lame solution, so I highly
suggest you take a look at Rob Williscroft's unsigned_int instead of
using bitset:

http://www.victim-prime.dsl.pipex.com/

Thanks for the tip. I'm just curious, how would I go about scanning the
upper 32 bits?

Thanks again.
 
M

Me

M said:
Thanks for the tip. I'm just curious, how would I go about scanning the
upper 32 bits?

You don't want to scan the upper 32 bits, you want to scan the upper 80
bits:

struct eqmySet {
bool operator()(const myBitSet &s1, const myBitSet &s2) const
{
for (size_t i = s1.size(); i != 0; --i) {
const int a = s1.test(i-1);
const int b = s2.test(i-1);
if (a != b)
return a < b;
}
return false;
}
};

Also, it looks like you've turned off exceptions because to_ulong() is
supposed to throw an exception if it can't fit (and you probably want
to rename this to lessmySet instead of eqmySet too).
 
O

Old Wolf

Me said:
Right here
Judging from the pragma you used in the original code, I'm guessing
you're on windows. unsigned longs on that platform are 32 bits so this
just uses the lower 32 bits of the bitset as the key.

to_ulong() has undefined behaviour if the bitset is bigger
than an unsigned long.
 
M

M

Me said:
You don't want to scan the upper 32 bits, you want to scan the upper 80
bits:

struct eqmySet {
bool operator()(const myBitSet &s1, const myBitSet &s2) const
{
for (size_t i = s1.size(); i != 0; --i) {
const int a = s1.test(i-1);
const int b = s2.test(i-1);
if (a != b)
return a < b;
}
return false;
}
};

Also, it looks like you've turned off exceptions because to_ulong() is
supposed to throw an exception if it can't fit (and you probably want
to rename this to lessmySet instead of eqmySet too).
\


Thanks again. Would you happen to know how to use Williscroft's unsigned_int
as far as from a project point of view? Do I just add the files to my
project ? or include one of the folders?
 
R

Rob Williscroft

M wrote in in comp.lang.c++:
Thanks again. Would you happen to know how to use Williscroft's
unsigned_int as far as from a project point of view? Do I just add the
files to my project ? or include one of the folders?

Unpack the zip file into a directory and include that directory.
You should then be able to compile this:

#include <iostream>
#include <ostream>
#include <iomanip>

#include "imp/unsigned_int.hpp"

int main()
{
imp::unsigned_int< 80 > u80("0xFFFF123457898979");
std::cout << std::hex << u80 << std::endl;
}

The .cpp files under the 'src' directory are just part of the
documentation/test's.

Rob.
 

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,780
Messages
2,569,614
Members
45,290
Latest member
JennaNies

Latest Threads

Top