|
From: Ioannis V. <iv...@em...> - 2003-07-11 22:07:34
|
> -----Original Message-----
> From: dev...@li...=20
> [mailto:dev...@li...] On Behalf=20
> Of Shane Bryldt
> Sent: Friday, July 11, 2003 11:53 PM
> To: Hossein Haeri
> Cc: C++
> Subject: Re: [Dev-C++] STL Map question
>=20
>=20
> Actually, since I had about 20 responses on this topic, none of which
> actually got close to the effect, nevermind the cause of the=20
> problem, I will
> try and explain the situation in more detail. However, to=20
> make the records
> clear, I don't expect to find an answer now. I have looked=20
> the code over a
> number of times, and had another expert which is admittedly=20
> significantly
> better with C++ and STL than myself, and even he cannot seem=20
> to find any
> problems which relate. Given old working code, and my new=20
> adjusted code,
> many changes were made but I cannot determine what is causing=20
> the problem.
>=20
> Now, the effect of the issue, is as follows. A network of 6,000-10,000
> active users at any given time is regulated by a security=20
> service. This
> service runs and connects like a user, with special=20
> priviledges. Anytime a
> user connects to the network, the services is informed, and=20
> the User is
> added to a global UserList. The network also has smaller=20
> units, known as
> Channels. Each Channel contains 3 UserList's as well. =20
> First, depicts all
> users in the Channel, the second depicts all the operators of=20
> the channel,
> and the third depicts the priviledged users who are not=20
> operators. 99% of
> the time, the code work fine. Users constantly added and=20
> removed from the
> list. Periodically, what seems like an issue without a=20
> pattern, the code
> will crash with a segmentation fault while trying to call
> "std::map<>::find()", with a valid key. Whether the key is=20
> in the map, is
> not definate, but the key passed in valid and should not have=20
> a problem
> being searched.
>=20
> This said, I have narrowed the issue down to one of 2 causes.=20
> 1) Either
> User's are being added to lists, and not being removed, and=20
> the UserLists
> are eventually gathering enough garbage that out of memory is being
> encountered.
In this case if you use the operator new as you should, an =
std::bad_alloc()
exception would be thrown (defined in <new>) and as you should you must =
have
at least a catch(std::bad_allloc) in main() to catch such exceptions and =
at
least make the problem known by displaying an error message and shutting
down the program properly).
> The application has a signal hook for out of=20
> memory, and it is
> not being raised.=20
Let's hope you mean a catch clause.
> So I am leaning more towards option 2) The=20
> User class is
> being deleted, without being removed from the UserList. =20
> However, I can find
> no indication of this in the code. The code is many=20
> thousands of lines, it
> is not a small project by any means. Providing the source=20
> for the issue,
> would require the entire project as the issue is not=20
> specifically a syntax
> issue, but rather a situational issue. I do believe something has
> invalidated a User class, which a UserList has a pointer to,=20
> and when trying
> to use it, is causing a segmentation fault. I'm sure most of=20
> the experts
> here will agree with my conclusion and realize tracing this=20
> problem is no
> easy task.
We must see at least the entire definitions of UserList and User. Can =
you
provide them?
=20
> I've considered some commercial products like Purify, or some=20
> other memory
> tracking products, but I have no experience with any, since=20
> I've never had
> an issue I couldn't resolve purely with GDB. Since the=20
> problem traces back
> most likely to an invalid pointer reference, does anyone have=20
> suggestions on
> how I could possibly detect where the pointer is being deleted?
I am not an expert, I am still learning (and unfortunately there is an
infinite number of things that I want to learn) but I think that if =
there
has been a more proper use of C++, the code would have been more bullet
proof. That is using the superior alternatives that C++ provides instead =
of
the old stuff that they exist to replace.
> I've
> considered the idea of using smart pointers to track the=20
> issue down, but
> again I'm not entirely certain of how to implement some code=20
> to track where
> the User is being deleted without being removed from the=20
> channels they are
> in... It could also potentially be an issue with overwritting=20
> memory, but
> with how often it is caused in exactly the same way, it's=20
> unlikely to be
> memory overbounding.
> I noticed a location where the key being used was being changed (a
> nickname), and in those cases, where the old code would just=20
> rename the
> nickname, I have now remove from the map and then readd to=20
> the map. When it
> tries to remove from the map is when it crashes. I can only=20
> assume that the
> problem is an invalid pointer, thus the map::find function is crashing
> because of invalid memory. The key was based on a const char=20
> *, but the
> other expert I consulted suggested using std::string to help track the
> problem until it is found... Changing to use std::string is=20
> how I determined
> that the key was still valid (because it had a copy of the=20
> nick instead of a
> pointer to the nick which may be invalidated at some point),=20
> and the key was
> still intact as far as I can remember, the pointer however=20
> caused GDB itself
> to indicate that the program crashed again from a call by=20
> GDB, when trying
> to access a member of the pointer.
>=20
>=20
> Okay, hopefully these details will clarify for all the people=20
> who tried to
> help... The problem itself is not something so simple as was=20
> suggested so
> far. However, Hossein did make one point that I should have realized
> myself. Not that it matters, but I should use empty()=20
> instead of size() =3D=3D
> 0, since it's possible empty() can execute faster than=20
> size().
Eh? Why? Both have the same speed, actually empty is usually=20
// inside the class definition
bool empty() const { return size()=3D=3D0; }
since map has to keep track of its size. In any case consider them as =
equal
(an equality comparison doesn't take time!).
> But speaking
> from the ANSI compliance, size() =3D=3D 0 is identical to empty()=20
> =3D=3D true in
> result, just not exection. That said, it will not affect the problem.
Yeap. Please provide us with the complete defintions of User and =
UserList.
:-)
Ioannis Vranos
=20
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net
|