this stl code crashes, why???

P

Paul

Hi,

Global operator new and delete are overloaded and I am using stl map
to store pointers, but this code crashes, can some one shed some
light???
Compiler: MS VC++ 6.0
STL: Shipped with Visual Studio.

#include <malloc.h>
#include <map>

using namespace std;
typedef map<void*,void*> PointersMap;

PointersMap gMemStore;

void* operator new(size_t size)
{
void * p = ::malloc(size);
gMemStore[p] = p;
return p;
}

void operator delete(void* p)
{
PointersMap::iterator it = gMemStore.find(p);
if(it != gMemStore.end())
gMemStore.erase(it);
::free(p);
}

int main(int argc, char* argv[])
{
return 0;
}

TIA.
-Paul.
 
D

David Hilsee

Paul said:
Hi,

Global operator new and delete are overloaded and I am using stl map
to store pointers, but this code crashes, can some one shed some
light???
Compiler: MS VC++ 6.0
STL: Shipped with Visual Studio.

#include <malloc.h>
#include <map>

using namespace std;
typedef map<void*,void*> PointersMap;

PointersMap gMemStore;

void* operator new(size_t size)
{
void * p = ::malloc(size);
gMemStore[p] = p;
return p;
}

void operator delete(void* p)
{
PointersMap::iterator it = gMemStore.find(p);
if(it != gMemStore.end())
gMemStore.erase(it);
::free(p);
}

int main(int argc, char* argv[])
{
return 0;
}

Well, I could see how this might cause infinite recursion. Your operator
new calls std::map<void*,void*>::eek:perator[] which could call operator new,
which calls std::map<void*,void*>::eek:perator[], which could call operator
new, etc. That's just a guess, because I do not have VC++6. Have you
considered using a debugger? It would probably give you a more
straightforward answer than this newgroup.
 
A

Alf P. Steinbach

* Paul:
Global operator new and delete are overloaded and I am using stl map
to store pointers, but this code crashes

That should read: and therefore this code crashes.

Try to search for "infinite recursion".

int main(int argc, char* argv[])
{
return 0;
}

This does not exercise the code and seems to serve no purpose.
 
P

PKH

Paul said:
Hi,

Global operator new and delete are overloaded and I am using stl map
to store pointers, but this code crashes, can some one shed some
light???
Compiler: MS VC++ 6.0
STL: Shipped with Visual Studio.

#include <malloc.h>
#include <map>

using namespace std;
typedef map<void*,void*> PointersMap;

PointersMap gMemStore;

void* operator new(size_t size)
{
void * p = ::malloc(size);
gMemStore[p] = p;
return p;
}

void operator delete(void* p)
{
PointersMap::iterator it = gMemStore.find(p);
if(it != gMemStore.end())
gMemStore.erase(it);
::free(p);
}

int main(int argc, char* argv[])
{
return 0;
}

TIA.
-Paul.

Do you crash with an out of stack-space message ?
The problem is probably as others have said that gMemStore[p] calls new,
giving an infinite loop.
You could create your own namespace to fix it, so you could use f.ex.
app::new and app::delete for you own code.

PKH
 
V

Vyacheslav Kononenko

using namespace std;
typedef map<void*,void*> PointersMap;

It will not solve the problem but

typedef set< void * > PointersMap;

would be more appropriate there IMHO. And there is erase method that
accepts key instead of iterator in std::map so you do not have to do
find/if/erase by yourself.
 
P

Paul

* Paul:

That should read: and therefore this code crashes.

Hmm, your point is valid, debugged but there is no infinite recursion.
I am analyzing stack trace, 'll post the reason soon, it doesn't even
call new again. I need to find out why.
Try to search for "infinite recursion".

int main(int argc, char* argv[])
{
return 0;
}

This does not exercise the code and seems to serve no purpose.

I wanted to show here that I am allocating nothing, still new is
getting called and resulting in a crash. who is calling new and why?
well I see that C Runtime is calling this, but why? Hmm looks like, I
found some thing to learn.

-Paul.
 
K

Karl Heinz Buchegger

Paul said:
* Paul:

That should read: and therefore this code crashes.

Hmm, your point is valid, debugged but there is no infinite recursion.
I am analyzing stack trace, 'll post the reason soon, it doesn't even
call new again. I need to find out why.
Try to search for "infinite recursion".

int main(int argc, char* argv[])
{
return 0;
}

This does not exercise the code and seems to serve no purpose.

I wanted to show here that I am allocating nothing, still new is
getting called and resulting in a crash. who is calling new and why?

Q: Well. What does your program do?
A: It creates a PointersMap object.
Q: So what is a PointersMap object?
A: it is a std::map<void*,void*>
Q: Could it be that when a std::map object
comes into existance, that it allocates something?
A: Hmm. Nobody knows for sure, but chances are high that
it does.
Q: But what does that mean?
A: It means that the global operator new is called, which
in turn uses the PointersMap object (which by the way is
not constructed fully right now) and tries to insert a pointer
in the map. As a consequence if this insertion, the PointersMap
object will need to allocate some memory which results in a call
to the global operator new, which in turn tries to insert the
pointer, which results in a call to global operator new ....
 
P

Paul

PKH said:
Paul said:
Hi,

Global operator new and delete are overloaded and I am using stl map
to store pointers, but this code crashes, can some one shed some
light???
Compiler: MS VC++ 6.0
STL: Shipped with Visual Studio.

#include <malloc.h>
#include <map>

using namespace std;
typedef map<void*,void*> PointersMap;

PointersMap gMemStore;

void* operator new(size_t size)
{
void * p = ::malloc(size);
gMemStore[p] = p;
return p;
}

void operator delete(void* p)
{
PointersMap::iterator it = gMemStore.find(p);
if(it != gMemStore.end())
gMemStore.erase(it);
::free(p);
}

int main(int argc, char* argv[])
{
return 0;
}

TIA.
-Paul.

Do you crash with an out of stack-space message ?
The problem is probably as others have said that gMemStore[p] calls new,
giving an infinite loop.
You could create your own namespace to fix it, so you could use f.ex.
app::new and app::delete for you own code.

PKH

there is absolutely no recursion and hence no out-of stack message. It
crashes at first insert, I didn't see second insert or some sort of
recursion in stack trace.
interested people can have a look at this stack trace.

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *>
::_Parent(std::_Tree<void *,std::pair<void * const,void
::_Kfn,std::less<void *>,std::allocator<void *> >::_Node *
0x00000000) line 42

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *> >::_Root() line 550

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *> >::insert(const
std::pair<void * const,void *> & {...}) line 217 + 40 bytes
//****crash while it is unwinding****//

std::map said:
::insert(const std::pair<void * const,void *> & {...}) line 96

std::pair<void * const,void *>::pair<void * const,void *>(void *
const & 0x002f1000, void * const & 0x00000000) line 21

std::map said:
::eek:perator[](void * const & 0x002f1000) line 93
operator new(unsigned int 24) line 17 + 14 bytes
std::_Allocate(int 24, char * 0x00000000) line 30 + 9 bytes
std::allocator<void *>::_Charalloc(unsigned int 24) line 62 + 11 bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Buynode(std::_Tree<void *,std::pair<void
* const,void *>,std::map<void *,void *,std::less<void
*>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Node * 0x00000000, ...) line 578 + 10
bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Init() line 450 + 62 bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Tree<void *,std::pair<void * const,void
*>,std::map<void *,void *,std::less<void 1ee72c23(const std::less<void
*> & {...}, unsigned char 0, const std::allocator<void *> & {...})
line 160 + 67 bytes
std::map said:
::map<void *,void *,std::less<void *>,std::allocator<void *> >(const
std::less<void *> & {...}, const std::allocator<void *> & {...}) line
57 + 47 bytes
$E3() line 12 + 42 bytes
$E6() + 29 bytes
_initterm(void (void)* * 0x0042a104 $S7, void (void)* * 0x0042a208
___xc_z) line 525
_cinit() line 192 + 15 bytes
mainCRTStartup() line 205
KERNEL32! 7c581af6()

The representation...
-e (d called e)
-d (c called d)
-c (a called c)
-b (a called b, b returned and then a called c)
-a

tia.
-Paul
 
D

David Hilsee

Paul said:
"PKH" <[email protected]> wrote in message
Paul said:
Hi,

Global operator new and delete are overloaded and I am using stl map
to store pointers, but this code crashes, can some one shed some
light???
Compiler: MS VC++ 6.0
STL: Shipped with Visual Studio.

#include <malloc.h>
#include <map>

using namespace std;
typedef map<void*,void*> PointersMap;

PointersMap gMemStore;

void* operator new(size_t size)
{
void * p = ::malloc(size);
gMemStore[p] = p;
return p;
}

void operator delete(void* p)
{
PointersMap::iterator it = gMemStore.find(p);
if(it != gMemStore.end())
gMemStore.erase(it);
::free(p);
}

int main(int argc, char* argv[])
{
return 0;
}

TIA.
-Paul.

Do you crash with an out of stack-space message ?
The problem is probably as others have said that gMemStore[p] calls new,
giving an infinite loop.
You could create your own namespace to fix it, so you could use f.ex.
app::new and app::delete for you own code.

PKH

there is absolutely no recursion and hence no out-of stack message. It
crashes at first insert, I didn't see second insert or some sort of
recursion in stack trace.
interested people can have a look at this stack trace.

I ran it on a copy of MSVC++6 I have at work, and you're right, it did not
crash because of the recursion. However, there most certainly _is_
recursion, and it would have infinitely recursed if it had been able to
continue. It looked like it crashed because the std::map's constructor had
not finished executing, so it was in an invalid state when operator[] was
first called. The constructor would up invoking operator new, which invoked
operator[] on the partially-constructed std::map.
 
A

Alf P. Steinbach

* Paul:
Do you crash with an out of stack-space message ?
The problem is probably as others have said that gMemStore[p] calls new,
giving an infinite loop.
You could create your own namespace to fix it, so you could use f.ex.
app::new and app::delete for you own code.

PKH

there is absolutely no recursion

That is incorrect.

and hence no out-of stack message.

The conclusion wouldn't follow from the premise if the premise was true.

It
crashes at first insert, I didn't see second insert or some sort of
recursion in stack trace.
interested people can have a look at this stack trace.

I and many others have already told you what the technical problem is.

It is recursion.

I've marked recursion below with "----------------- ^ -----------------".

::_Kfn,std::less<void *>,std::allocator<void *>
::_Parent(std::_Tree<void *,std::pair<void * const,void
::_Kfn,std::less<void *>,std::allocator<void *> >::_Node *
0x00000000) line 42

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *> >::_Root() line 550

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *> >::insert(const
std::pair<void * const,void *> & {...}) line 217 + 40 bytes
//****crash while it is unwinding****//

std::map said:
::insert(const std::pair<void * const,void *> & {...}) line 96

std::pair<void * const,void *>::pair<void * const,void *>(void *
const & 0x002f1000, void * const & 0x00000000) line 21

std::map said:
::eek:perator[](void * const & 0x002f1000) line 93

----------------- ^ -----------------

operator new(unsigned int 24) line 17 + 14 bytes
std::_Allocate(int 24, char * 0x00000000) line 30 + 9 bytes
std::allocator<void *>::_Charalloc(unsigned int 24) line 62 + 11 bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Buynode(std::_Tree<void *,std::pair<void
* const,void *>,std::map<void *,void *,std::less<void
*>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Node * 0x00000000, ...) line 578 + 10
bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Init() line 450 + 62 bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Tree<void *,std::pair<void * const,void
*>,std::map<void *,void *,std::less<void 1ee72c23(const std::less<void
*> & {...}, unsigned char 0, const std::allocator<void *> & {...})
line 160 + 67 bytes

std::less<void *> & {...}, const std::allocator<void *> & {...}) line

Called from here.
 
P

Paul

* Paul:
Do you crash with an out of stack-space message ?
The problem is probably as others have said that gMemStore[p] calls new,
giving an infinite loop.
You could create your own namespace to fix it, so you could use f.ex.
app::new and app::delete for you own code.

PKH

there is absolutely no recursion

That is incorrect.

and hence no out-of stack message.

The conclusion wouldn't follow from the premise if the premise was true.

It
crashes at first insert, I didn't see second insert or some sort of
recursion in stack trace.
interested people can have a look at this stack trace.

I and many others have already told you what the technical problem is.

It is recursion.
no its not, I agree this can cause recursion, but its not crashing due
to recursion. David Hilsee's response addresses it properly.
I modified the code to illustrate. this code'll not crash.
like David said, the construction is not complete.
It requests for memory - new allocates - but before returning the
pointer to allocated memory to map - it uses that memory - which is
why it crashes.
#include <malloc.h>
#include <map>

using namespace std;
typedef map<void*,void*> PointersMap;

PointersMap gMemStore;
bool bDone = false;

void* operator new(size_t size)
{
void * p = ::malloc(size);
if(bDone)
gMemStore[p] = p;
return p;
}

int main(int argc, char* argv[])
{
bDone = true;
// following line when un-commented, results a crash due to recursion.
// int *p = new int[10];
return 0;
}

thanks for your comments.

-Paul.
I've marked recursion below with "----------------- ^ -----------------".

::_Kfn,std::less<void *>,std::allocator<void *>
::_Parent(std::_Tree<void *,std::pair<void * const,void
::_Kfn,std::less<void *>,std::allocator<void *> >::_Node *
0x00000000) line 42

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *> >::_Root() line 550

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *> >::insert(const
std::pair<void * const,void *> & {...}) line 217 + 40 bytes
//****crash while it is unwinding****//

std::map said:
::insert(const std::pair<void * const,void *> & {...}) line 96

std::pair<void * const,void *>::pair<void * const,void *>(void *
const & 0x002f1000, void * const & 0x00000000) line 21

std::map said:
::eek:perator[](void * const & 0x002f1000) line 93

----------------- ^ -----------------

operator new(unsigned int 24) line 17 + 14 bytes
std::_Allocate(int 24, char * 0x00000000) line 30 + 9 bytes
std::allocator<void *>::_Charalloc(unsigned int 24) line 62 + 11 bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Buynode(std::_Tree<void *,std::pair<void
* const,void *>,std::map<void *,void *,std::less<void
*>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Node * 0x00000000, ...) line 578 + 10
bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Init() line 450 + 62 bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Tree<void *,std::pair<void * const,void
*>,std::map<void *,void *,std::less<void 1ee72c23(const std::less<void
*> & {...}, unsigned char 0, const std::allocator<void *> & {...})
line 160 + 67 bytes

std::less<void *> & {...}, const std::allocator<void *> & {...}) line

Called from here.

57 + 47 bytes
$E3() line 12 + 42 bytes
$E6() + 29 bytes
_initterm(void (void)* * 0x0042a104 $S7, void (void)* * 0x0042a208
___xc_z) line 525
_cinit() line 192 + 15 bytes
mainCRTStartup() line 205
KERNEL32! 7c581af6()

The representation...
-e (d called e)
-d (c called d)
-c (a called c)
-b (a called b, b returned and then a called c)
-a

tia.
-Paul
 
P

Paul

* Paul:
Do you crash with an out of stack-space message ?
The problem is probably as others have said that gMemStore[p] calls new,
giving an infinite loop.
You could create your own namespace to fix it, so you could use f.ex.
app::new and app::delete for you own code.

PKH

there is absolutely no recursion

That is incorrect.

and hence no out-of stack message.

The conclusion wouldn't follow from the premise if the premise was true.

It
crashes at first insert, I didn't see second insert or some sort of
recursion in stack trace.
interested people can have a look at this stack trace.

I and many others have already told you what the technical problem is.

It is recursion.

I've marked recursion below with "----------------- ^ -----------------".

::_Kfn,std::less<void *>,std::allocator<void *>
::_Parent(std::_Tree<void *,std::pair<void * const,void
::_Kfn,std::less<void *>,std::allocator<void *> >::_Node *
0x00000000) line 42

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *> >::_Root() line 550

std::_Tree said:
::_Kfn,std::less<void *>,std::allocator<void *> >::insert(const
std::pair<void * const,void *> & {...}) line 217 + 40 bytes
//****crash while it is unwinding****//

std::map said:
::insert(const std::pair<void * const,void *> & {...}) line 96

std::pair<void * const,void *>::pair<void * const,void *>(void *
const & 0x002f1000, void * const & 0x00000000) line 21

std::map said:
::eek:perator[](void * const & 0x002f1000) line 93

----------------- ^ -----------------

operator new(unsigned int 24) line 17 + 14 bytes
std::_Allocate(int 24, char * 0x00000000) line 30 + 9 bytes
std::allocator<void *>::_Charalloc(unsigned int 24) line 62 + 11 bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Buynode(std::_Tree<void *,std::pair<void
* const,void *>,std::map<void *,void *,std::less<void
*>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Node * 0x00000000, ...) line 578 + 10
bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Init() line 450 + 62 bytes
std::_Tree<void *,std::pair<void * const,void *>,std::map<void *,void
*,std::less<void *>,std::allocator<void *> >::_Kfn,std::less<void
*>,std::allocator<void *> >::_Tree<void *,std::pair<void * const,void
*>,std::map<void *,void *,std::less<void 1ee72c23(const std::less<void
*> & {...}, unsigned char 0, const std::allocator<void *> & {...})
line 160 + 67 bytes

std::less<void *> & {...}, const std::allocator<void *> & {...}) line

Called from here.

57 + 47 bytes
$E3() line 12 + 42 bytes
$E6() + 29 bytes
_initterm(void (void)* * 0x0042a104 $S7, void (void)* * 0x0042a208
___xc_z) line 525
_cinit() line 192 + 15 bytes
mainCRTStartup() line 205
KERNEL32! 7c581af6()

The representation...
-e (d called e)
-d (c called d)
-c (a called c)
-b (a called b, b returned and then a called c)
-a

tia.
-Paul

you are correct on both counts, incomplete construction and possible
recursion. Recursion is possible, but this crashes before even it
reaches there, due to incomplete construction.

thanks
-Paul.
 
P

Paul

David Hilsee said:
Paul said:
"PKH" <[email protected]> wrote in message
Hi,

Global operator new and delete are overloaded and I am using stl map
to store pointers, but this code crashes, can some one shed some
light???
Compiler: MS VC++ 6.0
STL: Shipped with Visual Studio.

#include <malloc.h>
#include <map>

using namespace std;
typedef map<void*,void*> PointersMap;

PointersMap gMemStore;

void* operator new(size_t size)
{
void * p = ::malloc(size);
gMemStore[p] = p;
return p;
}

void operator delete(void* p)
{
PointersMap::iterator it = gMemStore.find(p);
if(it != gMemStore.end())
gMemStore.erase(it);
::free(p);
}

int main(int argc, char* argv[])
{
return 0;
}

TIA.
-Paul.

Do you crash with an out of stack-space message ?
The problem is probably as others have said that gMemStore[p] calls new,
giving an infinite loop.
You could create your own namespace to fix it, so you could use f.ex.
app::new and app::delete for you own code.

PKH

there is absolutely no recursion and hence no out-of stack message. It
crashes at first insert, I didn't see second insert or some sort of
recursion in stack trace.
interested people can have a look at this stack trace.

I ran it on a copy of MSVC++6 I have at work, and you're right, it did not
crash because of the recursion. However, there most certainly _is_
recursion, and it would have infinitely recursed if it had been able to
continue. It looked like it crashed because the std::map's constructor had
not finished executing, so it was in an invalid state when operator[] was
first called. The constructor would up invoking operator new, which invoked
operator[] on the partially-constructed std::map.

you are correct on both counts, incomplete construction and possible
recursion. Recursion is possible, but this crashes before even it
reaches there, due to incomplete construction.

thanks
-Paul.

Pls. my second post under Alf P. Steinbach is a mistake, it should be here.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top