Hi everyone
I have this strange behaviour happening with this code which I can't
explain. On my computer when I set nt with a value greater than 3000
it crashes. Is there a max number of keys I can use with a std::map ?
thanks a lot
#include <vector>
#include <iostream>
#include <map>
#include <string>
int main()
{
float t = clock();
int nt = 3000;
#if 1
hash_map<std::string, int, hash<std::string> > mymap;
for ( int i = 0; i < nt; ++i )
{
string tmp = "test" + i;
mymap[ tmp ] = i;
}
for ( int i = 0; i < 10e5; ++i )
{
int a = (int)(drand48() * nt);
string tmp = "test" + a;
hash_map<std::string, int, hash<std::string> >::iterator it =
mymap.find( tmp );
if ( it != mymap.end() )
{
}
else
{
printf("not found\n");
}
}
unsigned max_size = mymap.max_size();
printf("%d\n", max_size );
#else
std::map<std::string, int> mymap;
for ( int i = 0; i < nt; ++i )
{
string tmp = "test" + i;
mymap[ tmp ] = i;
}
for ( int i = 0; i < 10e5; ++i )
{
int a = (int)(drand48() * nt);
string tmp = "test" + a;
std::map<std::string, int>::iterator it = mymap.find( tmp );
if ( it != mymap.end() )
{
}
else
{
printf("not found\n");
}
}
unsigned max_size = mymap.max_size();
printf("%d\n", max_size );
#endif
printf("time %f\n", (clock() - t ) / float( CLOCKS_PER_SEC ) );
return 0;
}
#endif
|
|
0
|
|
|
|
Reply
|
mast4as (30)
|
8/12/2010 5:33:22 PM |
|
Sorry you need to add
#include <ext/hash_map>
using namespace __gnu_cxx;
namespace __gnu_cxx {
// hash specialisation to allow hashing of strings
template<>
struct hash<std::string>
{
size_t operator()(const std::string &__s) const { return
__stl_hash_string(__s.c_str()); }
};
} // namespace __gnu_cxx OR std
at the top if you want this to compile. But hash_map and map behaves
the same
using c++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
On Aug 12, 6:33=A0pm, mast4as <mast...@yahoo.com> wrote:
> Hi everyone
>
> I have this strange behaviour happening with this code which I can't
> explain. On my computer when I set nt with a value greater than 3000
> it crashes. Is there a max number of keys I can use with a std::map ?
>
> thanks a lot
>
> #include <vector>
> #include <iostream>
> #include <map>
>
> #include <string>
>
> int main()
> {
> =A0 =A0 =A0 =A0 float t =3D clock();
> =A0 =A0 =A0 =A0 int nt =3D 3000;
> #if 1
> =A0 =A0 =A0 =A0 hash_map<std::string, int, hash<std::string> > mymap;
> =A0 =A0 =A0 =A0 for ( int i =3D 0; i < nt; ++i )
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 string tmp =3D "test" + i;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mymap[ tmp ] =3D i;
> =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 for ( int i =3D 0; i < 10e5; ++i )
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int a =3D (int)(drand48() * nt);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 string tmp =3D "test" + a;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 hash_map<std::string, int, hash<std::stri=
ng> >::iterator it =3D
> mymap.find( tmp );
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ( it !=3D mymap.end() )
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printf("not found\n");
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 unsigned max_size =3D mymap.max_size();
> =A0 =A0 =A0 =A0 printf("%d\n", max_size );
>
> #else
> =A0 =A0 =A0 =A0 std::map<std::string, int> mymap;
> =A0 =A0 =A0 =A0 for ( int i =3D 0; i < nt; ++i )
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 string tmp =3D "test" + i;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mymap[ tmp ] =3D i;
> =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 for ( int i =3D 0; i < 10e5; ++i )
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int a =3D (int)(drand48() * nt);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 string tmp =3D "test" + a;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 std::map<std::string, int>::iterator it =
=3D mymap.find( tmp );
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ( it !=3D mymap.end() )
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 printf("not found\n");
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0 unsigned max_size =3D mymap.max_size();
> =A0 =A0 =A0 =A0 printf("%d\n", max_size );
>
> #endif
> =A0 =A0 =A0 =A0 printf("time %f\n", (clock() - t ) / float( CLOCKS_PER_SE=
C ) );
>
> =A0 =A0 =A0 =A0 return 0;
>
> }
>
> #endif
|
|
0
|
|
|
|
Reply
|
mast4as (30)
|
8/12/2010 5:34:57 PM
|
|
On Aug 12, 12:33=A0pm, mast4as <mast...@yahoo.com> wrote:
> Hi everyone
>
> I have this strange behaviour happening with this code which I can't
> explain. On my computer when I set nt with a value greater than 3000
> it crashes. Is there a max number of keys I can use with a std::map ?
>
It's because this doesn't do what you think it does:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 string tmp =3D "test" + i;
It does *not* make a string named "test1", "test2", etc.
Instead, it does pointer arithmetic on the const char*
that points to "test".
So
("test" + 0) is a pointer to the string "test"
("test" + 1) is a pointer to the string "est"
("test" + 2) is a pointer to the string "st"
etc.
Once i passes the null byte in the string literal, though,
you're into some random chunk of memory. All bets are off.
Eventually you're reading outside of memory that belongs
to your application and you get a segfault.
--Jonathan
|
|
0
|
|
|
|
Reply
|
jonathan.lee.975 (31)
|
8/12/2010 5:49:01 PM
|
|
On Aug 12, 6:49=A0pm, Jonathan Lee <jonathan.lee....@gmail.com> wrote:
> On Aug 12, 12:33=A0pm, mast4as <mast...@yahoo.com> wrote:
>
> > Hi everyone
>
> > I have this strange behaviour happening with this code which I can't
> > explain. On my computer when I set nt with a value greater than 3000
> > it crashes. Is there a max number of keys I can use with a std::map ?
>
> It's because this doesn't do what you think it does:
>
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 string tmp =3D "test" + i;
>
> It does *not* make a string named "test1", "test2", etc.
> Instead, it does pointer arithmetic on the const char*
> that points to "test".
>
> So
> =A0 =A0("test" + 0) is a pointer to the string "test"
> =A0 =A0("test" + 1) is a pointer to the string "est"
> =A0 =A0("test" + 2) is a pointer to the string "st"
>
> etc.
>
> Once i passes the null byte in the string literal, though,
> you're into some random chunk of memory. All bets are off.
> Eventually you're reading outside of memory that belongs
> to your application and you get a segfault.
>
> --Jonathan
Thanks a lot yes ... I just figured (long day at work ;-(
Thank you so much
std::string createRandomString()
{
char alpha[ 6 ] =3D { 'a', 'b', 'c', 'd', 'e', 'f' };
char str[ 10 ];
for ( int i =3D 0 ; i < 10 ; i++ )
{
int a =3D int(drand48()*5);
str[ i ] =3D a;
}
return std::string( str );
}
int main()
{
float t =3D clock();
int nt =3D 10000;
#if 1
hash_map<std::string, int, hash<std::string> > mymap;
for ( int i =3D 0; i < nt; ++i )
{
string tmp =3D createRandomString();
mymap[ tmp ] =3D i;
}
for ( int i =3D 0; i < 10e5; ++i )
{
int a =3D (int)(drand48() * nt);
string tmp =3D createRandomString();
hash_map<std::string, int, hash<std::string> >::iterator it =3D
mymap.find( tmp );
if ( it !=3D mymap.end() )
{
}
else
{
//printf("not found\n");
}
}
unsigned max_size =3D mymap.max_size();
printf("%d\n", max_size );
#else
std::map<std::string, int> mymap;
for ( int i =3D 0; i < nt; ++i )
{
string tmp =3D createRandomString();
mymap[ tmp ] =3D i;
}
for ( int i =3D 0; i < 10e5; ++i )
{
int a =3D (int)(drand48() * nt);
string tmp =3D createRandomString();
std::map<std::string, int>::iterator it =3D mymap.find( tmp );
if ( it !=3D mymap.end() )
{
}
else
{
//printf("not found\n");
}
}
unsigned max_size =3D mymap.max_size();
printf("%d\n", max_size );
#endif
printf("time %f\n", (clock() - t ) / float( CLOCKS_PER_SEC ) );
return 0;
}
#endif
|
|
0
|
|
|
|
Reply
|
mast4as (30)
|
8/12/2010 5:56:03 PM
|
|
On Aug 12, 12:56=A0pm, mast4as <mast...@yahoo.com> wrote:
> Thanks a lot yes ... I just figured (long day at work ;-(
>
> Thank you so much
> std::string createRandomString()
> {
> =A0 =A0 =A0 =A0 char alpha[ 6 ] =3D { 'a', 'b', 'c', 'd', 'e', 'f' };
> =A0 =A0 =A0 =A0 char str[ 10 ];
> =A0 =A0 =A0 =A0 for ( int i =3D 0 ; i < 10 ; i++ )
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int a =3D int(drand48()*5);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 str[ i ] =3D a;
> =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 return std::string( str );
>
> }
No problem. BTW, if you want to avoid these random strings
you could probably use next_permutation from <algorithm>
to get some string names. Make a char array of distinct
letters, permute them, and use string::append to get your
dummy string.
(Not entirely related, just something I've found useful
before)
--Jonathan
|
|
0
|
|
|
|
Reply
|
jonathan.lee.975 (31)
|
8/12/2010 6:03:14 PM
|
|
|
4 Replies
108 Views
(page loaded in 0.887 seconds)
|