URGENT: STL std::map<ULONG, CEvent> 
Author Message
 URGENT: STL std::map<ULONG, CEvent>

Hello,
Here is my Class CEvent that I use in my std::map.
***************************************
DEFINITION:
class CEvent
{public:
 CEvent();
 ~CEvent();

 // Copy Constructor
 CEvent(const CEvent&);

private:
 HANDLE m_hEvent;};

IMPLEMENTATION:
static HANDLE Create();

CEvent::CEvent()
 : m_hEvent(Create()){}

// Copy Constructor
CEvent::CEvent(const CEvent& rhs){
 m_hEvent = rhs.m_hEvent;} // IS THIS INCORRECT?

CEvent::~CEvent()
{ ::CloseHandle(m_hEvent);}

// Helper function
static HANDLE Create()
{ HANDLE handle = ::CreateEvent(0,true,false,0);
 return handle;}
*****************************************
and my main()
*****************************************
#include <map>
#include "CEvent.h"

int main()
{
 typedef std::map<ULONG,CEvent> HANDLELIST;
 HANDLELIST handleList;
 HANDLELIST::iterator ihandleList;

 handleList[1]; // ERROR HERE!!

return 0;}
******************************************

I get the following error (no error during compilation) when running the
code:
First chance exception in Program.exe (NTDLL.DLL): 0xC0000008: Invalid
Handle

I think the code is trying to delete the same memory twice.
Is my copy constructor incorrect?

Thanks,
Sami



Fri, 25 Nov 2005 04:03:38 GMT  
 URGENT: STL std::map<ULONG, CEvent>
In general, it's incorrect.
Handles get copyed/duplicated with the DuplicateHandle() API.
You are not implementing an assignment operator, and,
your SC++L implementation may use it,
force the compiler to syntethyze one for you, with bitwise copy semantic.
Adding an element to a map by using the std::map<>::operator[]
is 'obscure', to say the least, but if you read the implementation,
you will see that the temporay object passed to the insert() method
is destoyed at the end of the expression, and since bitwise copy semantic is
used,
the container will have a bitwaise copy of an invalid handle.
when the container goes out-of scope, you will close an invalid handle.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


Quote:
> Hello,
> Here is my Class CEvent that I use in my std::map.
> ***************************************
> DEFINITION:
> class CEvent
> {public:
>  CEvent();
>  ~CEvent();

>  // Copy Constructor
>  CEvent(const CEvent&);

> private:
>  HANDLE m_hEvent;};

> IMPLEMENTATION:
> static HANDLE Create();

> CEvent::CEvent()
>  : m_hEvent(Create()){}

> // Copy Constructor
> CEvent::CEvent(const CEvent& rhs){
>  m_hEvent = rhs.m_hEvent;} // IS THIS INCORRECT?

> CEvent::~CEvent()
> { ::CloseHandle(m_hEvent);}

> // Helper function
> static HANDLE Create()
> { HANDLE handle = ::CreateEvent(0,true,false,0);
>  return handle;}
> *****************************************
> and my main()
> *****************************************
> #include <map>
> #include "CEvent.h"

> int main()
> {
>  typedef std::map<ULONG,CEvent> HANDLELIST;
>  HANDLELIST handleList;
>  HANDLELIST::iterator ihandleList;

>  handleList[1]; // ERROR HERE!!

> return 0;}
> ******************************************

> I get the following error (no error during compilation) when running the
> code:
> First chance exception in Program.exe (NTDLL.DLL): 0xC0000008: Invalid
> Handle

> I think the code is trying to delete the same memory twice.
> Is my copy constructor incorrect?

> Thanks,
> Sami



Fri, 25 Nov 2005 05:19:47 GMT  
 URGENT: STL std::map<ULONG, CEvent>
In other words I would have to implement an asignment operator and use
Duplicatehandle() API. Moreover I would have to use the insert() operator to
insert an Object in map.
Did I get it right?

Thanks,
Sami



Fri, 25 Nov 2005 18:21:59 GMT  
 URGENT: STL std::map<ULONG, CEvent>
Hello,
Here is my new Copy constructor and main()
**********************************
// Copy Constructor
CEvent::CEvent(const CEvent& rhs)
{
 BOOL fSuccess;
 fSuccess = ::DuplicateHandle(GetCurrentProcess(), rhs.m_hEvent,
     GetCurrentProcess(), &m_hEvent, 0,
     FALSE,
     DUPLICATE_SAME_ACCESS);
Quote:
}

*********************************
************************************************
CEvent sample_event;
cout << "Original handle of the temporary Event object: " << sample_event <<
endl;
handleList.insert(HANDLELIST::value_type(1,sample_event));
ihandleList = handleList.begin();
cout << "Saved handle of the Event object: " << ihandleList->second << endl;
************************************************

Can you tell me why my Copy Constructor gets called twice?
btw. No assignment operator is called for my CEvent class.

The program does not crash but when I output my handle values I get 2
different values.

Sami



Fri, 25 Nov 2005 20:51:43 GMT  
 URGENT: STL std::map<ULONG, CEvent>

Quote:

> Adding an element to a map by using the std::map<>::operator[]
> is 'obscure', to say the least

I don't know that I agree.  It's a potential gotcha, and probably
should be commented so that it's clear that the side effect of
inserting was considered, but it's the most concise way of getting
that behavior.

--
Craig Powers
MVP - Visual C++



Fri, 25 Nov 2005 22:48:17 GMT  
 URGENT: STL std::map<ULONG, CEvent>

Quote:

> Moreover I would have to use the insert() operator to insert an
> Object in map.

No.  insert() is (IMO) more appropriate for your usage of operator[],
but I don't think it's necessary.

--
Craig Powers
MVP - Visual C++



Fri, 25 Nov 2005 22:50:41 GMT  
 URGENT: STL std::map<ULONG, CEvent>
By looking at the implementation of SC++L on my machine:

This is the operator[]

 _Tref operator[](const key_type& _Kv)
  {iterator _P = insert(value_type(_Kv, _Ty())).first;
  return ((*_P).second); }

and it constructs a temporary _Ty() object,
plus there is one more constuction done deep down the
_Insert() member inside the <xtree> include.

Fortunately or Unfortunately , most SC++L implementation
employ deep copy many many times.
That's when it's time to have containers of proxy object
that holds a refcount to a real object (RefHolders objects).
In this case you pay the cost of an InterlockedIncrement
instread of a cost of a DuplicateHandle.

Usage of the assignment operator may come handy in other containers,
depending on their implementation.
You can make it private and explicit, with no body,
so that the compiler will scream as soon as it needs it for real.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


Quote:
> Hello,
> Here is my new Copy constructor and main()
> **********************************
> // Copy Constructor
> CEvent::CEvent(const CEvent& rhs)
> {
>  BOOL fSuccess;
>  fSuccess = ::DuplicateHandle(GetCurrentProcess(), rhs.m_hEvent,
>      GetCurrentProcess(), &m_hEvent, 0,
>      FALSE,
>      DUPLICATE_SAME_ACCESS);
> }
> *********************************
> ************************************************
> CEvent sample_event;
> cout << "Original handle of the temporary Event object: " << sample_event
<<
> endl;
> handleList.insert(HANDLELIST::value_type(1,sample_event));
> ihandleList = handleList.begin();
> cout << "Saved handle of the Event object: " << ihandleList->second <<
endl;
> ************************************************

> Can you tell me why my Copy Constructor gets called twice?
> btw. No assignment operator is called for my CEvent class.

> The program does not crash but when I output my handle values I get 2
> different values.

> Sami



Sat, 26 Nov 2005 01:07:48 GMT  
 URGENT: STL std::map<ULONG, CEvent>



Quote:
> By looking at the implementation of SC++L on my machine:

> This is the operator[]

>  _Tref operator[](const key_type& _Kv)
>   {iterator _P = insert(value_type(_Kv, _Ty())).first;
>   return ((*_P).second); }

> and it constructs a temporary _Ty() object,
> plus there is one more constuction done deep down the
> _Insert() member inside the <xtree> include.

> Fortunately or Unfortunately , most SC++L implementation
> employ deep copy many many times.

In this case because they were required. The C++ Standard explicitly
says:

T& operator[] (const key_type& x);

Returns: (*((insert(make_pair(x, T()))).first)).second

Doesn't leave much room for the implementor, does it?  :-)

The code you have is kind of a preview of the relaxed requirements in
the upcoming revision.

Bo Persson



Sat, 26 Nov 2005 03:32:21 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Help needed on std::map<>

2. std::map< a , b >::lower_bound(c)

3. Help needed on std::map<>

4. Implementing IDictionary on STL map<>

5. <<<<<<<Parsing help, please>>>>>>>>

6. STL's map<> item reorder

7. STL map<string, IHTMLElement*> Elements

8. STL's map<> item reorder

9. Win32 Debug vs.Win32 Release STL map<short, object*>::iterator

10. Warnings using STL Map<string,string>

11. Warnings for std::vector<std::string>

12. File Format conversion, ascii freeform -->.csv <-->.wk1<-->dbf<-->?HELP

 

 
Powered by phpBB® Forum Software