|
From: Shane B. <ast...@te...> - 2003-07-09 21:54:51
|
Hello,
I recently ran into an issue that I can't seem to pinpoint the cause =
of. 99% of the time, it seems to work, so it seems to be a small =
situational bug. Subject, is a UserList class, which internally =
implements an STL map. I am not sure why, but it seems to crash =
occasionally when I attempt to call the map::find function, with a valid =
null terminated char array. The map template implements a simple case =
insensative comparison. As I said, it works more often than not, but =
for some reason when attempting to delete from the list sometimes, it =
causes a SEGFAULT. Here is what GDB has to say:
Program received signal SIGSEGV, Segmentation fault.
0x80bb142 in _Rb_tree<char const *, pair<char const *const, User *>, =
_Select1st<pair<char const *const, User *> >, UserList::ltstr, =
allocator<User *> >::find (
this=3D0xbf14b30, __k=3D@0xbfbff7bc) at =
/usr/include/g++/stl_tree.h:1118
1118 _Link_type __x =3D _M_root(); // Current node.=20
(gdb) up
#1 0x80bb529 in map<char const *, User *, UserList::ltstr, =
allocator<User *> >::find (this=3D0xbf14b30, __x=3D@0xbfbff7bc) at =
/usr/include/g++/stl_map.h:187
187 iterator find(const key_type& __x) { return _M_t.find(__x); }
(gdb) up
#2 0x80ba8e9 in UserList::DeleteUser (this=3D0xbf14b30,=20
pNick=3D0xbf12300 "_=C7=E1=DF=D1=D2_") at UserList.cpp:26
26 UserMap::iterator it =3D m_mapUsers.find(pNick);
(gdb) print pNick
$1 =3D 0xbf12300 "_=C7=E1=DF=D1=D2_"
And here is the code in question.
bool UserList::DeleteUser(const char *pNick)
{
bool bRet =3D false;
=20
if(m_mapUsers.size() > 0)
{
UserMap::iterator it =3D m_mapUsers.find(pNick);
if(it !=3D m_mapUsers.end())
{
m_mapUsers.erase(it);
bRet =3D true;
}
}
return bRet;
}
My first thought was that the MAP container had issues when attempting =
to "find" with 0 elements, but that didn't seem to affect anything. Any =
thoughts?
-Shane |
|
From: Ioannis V. <iv...@em...> - 2003-07-09 22:41:15
|
-----Original Message-----
From: dev...@li...
[mailto:dev...@li...] On Behalf Of Shane =
Bryldt
Sent: Thursday, July 10, 2003 12:54 AM
To: C++
Subject: [Dev-C++] STL Map question
Hello,
=20
I recently ran into an issue that I can't seem to pinpoint the cause =
of.
99% of the time, it seems to work, so it seems to be a small situational
bug. Subject, is a UserList class, which internally implements an STL =
map.
I am not sure why, but it seems to crash occasionally when I attempt to =
call
the map::find function, with a valid null terminated char array. The =
map
template implements a simple case insensative comparison. As I said, it
works more often than not, but for some reason when attempting to delete
from the list sometimes, it causes a SEGFAULT. Here is what GDB has to =
say:
=20
Program received signal SIGSEGV, Segmentation fault.
0x80bb142 in _Rb_tree<char const *, pair<char const *const, User *>,
_Select1st<pair<char const *const, User *> >, UserList::ltstr,
allocator<User *> >::find (
this=3D0xbf14b30, __k=3D@0xbfbff7bc) at =
/usr/include/g++/stl_tree.h:1118
1118 _Link_type __x =3D _M_root(); // Current node.=20
(gdb) up
#1 0x80bb529 in map<char const *, User *, UserList::ltstr, =
allocator<User
*> >::find (this=3D0xbf14b30, __x=3D@0xbfbff7bc) at
/usr/include/g++/stl_map.h:187
187 iterator find(const key_type& __x) { return _M_t.find(__x); }
(gdb) up
#2 0x80ba8e9 in UserList::DeleteUser (this=3D0xbf14b30,=20
pNick=3D0xbf12300 "_=C7=E1=DF=D1=D2_") at UserList.cpp:26
26 UserMap::iterator it =3D m_mapUsers.find(pNick);
(gdb) print pNick
$1 =3D 0xbf12300 "_=C7=E1=DF=D1=D2_"
=20
=20
And here is the code in question.
=20
bool UserList::DeleteUser(const char *pNick)
{
bool bRet =3D false;
=20
if(m_mapUsers.size() > 0)
{
UserMap::iterator it =3D m_mapUsers.find(pNick);
if(it !=3D m_mapUsers.end())
{
m_mapUsers.erase(it);
bRet =3D true;
}
}
=20
return bRet;
}
=20
My first thought was that the MAP container had issues when attempting =
to
"find" with 0 elements, but that didn't seem to affect anything. Any
thoughts?=20
=20
Are you sure that m_mapUsers is an object of type UserMap and UserMap is =
a
typedef of a map type?
=20
=20
=20
=20
=20
=20
Ioannis Vranos
* Programming pages: http://www.noicys.freeurl.com
<http://www.noicys.freeurl.com/>=20
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net =
<http://www.noicys.cjb.net/>
=20
|
|
From: Shane B. <ast...@te...> - 2003-07-09 23:00:54
|
MessageYes, I appologize for not including the header definition. Here =
it is.
#ifndef USERLIST_H
#define USERLIST_H
=20
#include <map.h>
=20
class User;
=20
class UserList {
public:
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
typedef std::map<const char *, User *, ltstr> UserMap;
=20
UserList();
~UserList();
=20
void AddUser(User *pUser);
bool DeleteUser(const char *pNick);
User *FindUser(const char *pNick);
unsigned long Length();
=20
UserMap m_mapUsers;
};
=20
=20
#endif
-Shane
----- Original Message -----=20
From: Ioannis Vranos=20
To: 'C++'=20
Sent: Wednesday, July 09, 2003 4:41 PM
Subject: RE: [Dev-C++] STL Map question
-----Original Message-----
From: dev...@li... =
[mailto:dev...@li...] On Behalf Of Shane =
Bryldt
Sent: Thursday, July 10, 2003 12:54 AM
To: C++
Subject: [Dev-C++] STL Map question
Hello,
I recently ran into an issue that I can't seem to pinpoint the =
cause of. 99% of the time, it seems to work, so it seems to be a small =
situational bug. Subject, is a UserList class, which internally =
implements an STL map. I am not sure why, but it seems to crash =
occasionally when I attempt to call the map::find function, with a valid =
null terminated char array. The map template implements a simple case =
insensative comparison. As I said, it works more often than not, but =
for some reason when attempting to delete from the list sometimes, it =
causes a SEGFAULT. Here is what GDB has to say:
Program received signal SIGSEGV, Segmentation fault.
0x80bb142 in _Rb_tree<char const *, pair<char const *const, User *>, =
_Select1st<pair<char const *const, User *> >, UserList::ltstr, =
allocator<User *> >::find (
this=3D0xbf14b30, __k=3D@0xbfbff7bc) at =
/usr/include/g++/stl_tree.h:1118
1118 _Link_type __x =3D _M_root(); // Current node.=20
(gdb) up
#1 0x80bb529 in map<char const *, User *, UserList::ltstr, =
allocator<User *> >::find (this=3D0xbf14b30, __x=3D@0xbfbff7bc) at =
/usr/include/g++/stl_map.h:187
187 iterator find(const key_type& __x) { return =
_M_t.find(__x); }
(gdb) up
#2 0x80ba8e9 in UserList::DeleteUser (this=3D0xbf14b30,=20
pNick=3D0xbf12300 "_=C7=E1=DF=D1=D2_") at UserList.cpp:26
26 UserMap::iterator it =3D m_mapUsers.find(pNick);
(gdb) print pNick
$1 =3D 0xbf12300 "_=C7=E1=DF=D1=D2_"
And here is the code in question.
bool UserList::DeleteUser(const char *pNick)
{
bool bRet =3D false;
=20
if(m_mapUsers.size() > 0)
{
UserMap::iterator it =3D m_mapUsers.find(pNick);
if(it !=3D m_mapUsers.end())
{
m_mapUsers.erase(it);
bRet =3D true;
}
}
return bRet;
}
My first thought was that the MAP container had issues when =
attempting to "find" with 0 elements, but that didn't seem to affect =
anything. Any thoughts?=20
Are you sure that m_mapUsers is an object of type UserMap and UserMap =
is a typedef of a map type?
Ioannis Vranos
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net=20
|
|
From: Ioannis V. <iv...@em...> - 2003-07-10 00:10:59
|
=20
-----Original Message-----
From: dev...@li...
[mailto:dev...@li...] On Behalf Of Shane =
Bryldt
Sent: Thursday, July 10, 2003 2:00 AM
To: Ioannis Vranos
Cc: C++
Subject: Re: [Dev-C++] STL Map question
Yes, I appologize for not including the header definition. Here it is.
=20
#ifndef USERLIST_H
#define USERLIST_H
=20
#include <map.h>=20
=20
#include <cmap>
=20
=20
class User;
=20
class UserList {
public:
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}=20
=20
Why don't you use std::string?
=20
=20
};
typedef std::map<const char *, User *, ltstr> UserMap;
=20
UserList();
~UserList();
=20
void AddUser(User *pUser);
bool DeleteUser(const char *pNick);
User *FindUser(const char *pNick);
unsigned long Length();
=20
UserMap m_mapUsers;
};
=20
=20
#endif=20
=20
=20
This is really dangerous stuff! At first keep in mind that in the code:
=20
=20
UserList whatever;
=20
// ...
=20
whatever.FindUser("Johnson");
=20
whatever.FindUser("Johnson");
=20
=20
These two "Johnson" have different addresses! So better use std::string.
=20
=20
The specific portion of code you had provided and suspected that it =
crashes,
seems clean. The crash must occur somewhere else (soemwhere in those =
char
*s).
=20
Use std::string now! :-)
=20
=20
=20
=20
Ioannis Vranos
* Programming pages: http://www.noicys.freeurl.com
<http://www.noicys.freeurl.com/>=20
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net =
<http://www.noicys.cjb.net/>
=20
|
|
From: Per W. <pw...@ia...> - 2003-07-10 00:27:29
|
Did I miss something?
The compare function doesn't look for similar addresses - it performs a
full string compare. How would std::string make a difference?
The only important thing is that the users own their different names, and
doesn't have the name point to a auto-declared text buffer used during the
creation.
/Per W
On Thu, 10 Jul 2003, Ioannis Vranos wrote:
>
>
> -----Original Message-----
> From: dev...@li...
> [mailto:dev...@li...] On Behalf Of Shane Bryldt
> Sent: Thursday, July 10, 2003 2:00 AM
> To: Ioannis Vranos
> Cc: C++
> Subject: Re: [Dev-C++] STL Map question
>
>
> Yes, I appologize for not including the header definition. Here it is.
>
> #ifndef USERLIST_H
> #define USERLIST_H
>
> #include <map.h>
>
>
> #include <cmap>
>
>
>
> class User;
>
> class UserList {
> public:
> struct ltstr
> {
> bool operator()(const char* s1, const char* s2) const
> {
> return strcmp(s1, s2) < 0;
> }
>
>
> Why don't you use std::string?
>
>
>
> };
> typedef std::map<const char *, User *, ltstr> UserMap;
>
> UserList();
> ~UserList();
>
> void AddUser(User *pUser);
> bool DeleteUser(const char *pNick);
> User *FindUser(const char *pNick);
> unsigned long Length();
>
> UserMap m_mapUsers;
> };
>
>
> #endif
>
>
>
> This is really dangerous stuff! At first keep in mind that in the code:
>
>
> UserList whatever;
>
> // ...
>
> whatever.FindUser("Johnson");
>
> whatever.FindUser("Johnson");
>
>
> These two "Johnson" have different addresses! So better use std::string.
>
>
> The specific portion of code you had provided and suspected that it crashes,
> seems clean. The crash must occur somewhere else (soemwhere in those char
> *s).
>
> Use std::string now! :-)
>
>
>
>
> Ioannis Vranos
>
> * Programming pages: http://www.noicys.freeurl.com
> <http://www.noicys.freeurl.com/>
> * Alternative URL 1: http://run.to/noicys
> * Alternative URL 2: http://www.noicys.cjb.net <http://www.noicys.cjb.net/>
>
>
>
|
|
From: Ioannis V. <iv...@em...> - 2003-07-10 00:33:03
|
> -----Original Message----- > From: Per Westermark [mailto:pw...@ia...] > Sent: Thursday, July 10, 2003 3:29 AM > To: Ioannis Vranos > Cc: Dev-C++ Mailing List > Subject: RE: [Dev-C++] STL Map question > > > Did I miss something? > > The compare function doesn't look for similar addresses - it > performs a > full string compare. How would std::string make a difference? In the implementations of void AddUser(User *pUser); bool DeleteUser(const char *pNick); User *FindUser(const char *pNick); in someone of which it probably crashes. Ioannis Vranos * Programming pages: http://www.noicys.freeurl.com * Alternative URL 1: http://run.to/noicys * Alternative URL 2: http://www.noicys.cjb.net |
|
From: Per W. <pw...@ia...> - 2003-07-10 06:03:01
|
Yes, with char* AddUser etc must do strdup() or similar of the strings, to make them available for the lifetime of the user objects. However, when locating entries, it doesn't matter if the strings sent in to the Find() have different addresses. /Per W On Thu, 10 Jul 2003, Ioannis Vranos wrote: > > -----Original Message----- > > From: Per Westermark [mailto:pw...@ia...] > > Sent: Thursday, July 10, 2003 3:29 AM > > To: Ioannis Vranos > > Cc: Dev-C++ Mailing List > > Subject: RE: [Dev-C++] STL Map question > > > > > > Did I miss something? > > > > The compare function doesn't look for similar addresses - it > > performs a > > full string compare. How would std::string make a difference? > > > In the implementations of > > > void AddUser(User *pUser); > bool DeleteUser(const char *pNick); > User *FindUser(const char *pNick); > > > in someone of which it probably crashes. > > > > > > > Ioannis Vranos > > * Programming pages: http://www.noicys.freeurl.com > * Alternative URL 1: http://run.to/noicys > * Alternative URL 2: http://www.noicys.cjb.net > > > > > > > > ------------------------------------------------------- > This SF.Net email sponsored by: Parasoft > Error proof Web apps, automate testing & more. > Download & eval WebKing and get a free book. > www.parasoft.com/bulletproofapps > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > |
|
From: Ioannis V. <iv...@em...> - 2003-07-10 12:12:31
|
> -----Original Message-----
> From: Per Westermark [mailto:pw...@ia...]
> Sent: Thursday, July 10, 2003 9:05 AM
> To: Ioannis Vranos
> Cc: Dev-C++ Mailing List
> Subject: RE: [Dev-C++] STL Map question
>
>
> Yes, with char* AddUser etc must do strdup() or similar of
> the strings, to
> make them available for the lifetime of the user objects.
>
> However, when locating entries, it doesn't matter if the
> strings sent in
> to the Find() have different addresses.
Yes. However the definition she suspects that has the bug:
bool UserList::DeleteUser(const char *pNick)
{
bool bRet = false;
if(m_mapUsers.size() > 0)
{
UserMap::iterator it = m_mapUsers.find(pNick);
if(it != m_mapUsers.end())
{
m_mapUsers.erase(it);
bRet = true;
}
}
return bRet;
}
As I said it is OK.
However the member functions
void AddUser(User *pUser);
User *FindUser(const char *pNick);
are a different story (I included in this list the DeleteUser() from
rashness).
Ioannis Vranos
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net
|