Click here to Skip to main content
15,867,488 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Can anyone tell me how does stl's map.insert() works?.Does it call new . i am facing a problem .i have overloaded new in my code and i guess map.insert is also using the overloaded new instead of the global new.Is their anyway in which i could achieve this..basically i want map.insert() to call the global new and not the overloaded new
Posted
Updated 15-Feb-12 0:32am
v2
Comments
Emilio Garavaglia 15-Feb-12 8:10am    
Did you overload new globally or as a member operator of your class?
Are you staring your objects in the map or just pointers ?
Member 8576081 16-Feb-12 5:24am    
i have overloaded it globally
Emilio Garavaglia 17-Feb-12 9:14am    
Please don't post further question or messages to answer's authors as "solutions". Use the "have question or comment" button for that, otherwise the authors will not be notified of your requests.

std::map::insert creates a map node that is a private structure containing a copy of the key and a copy of the value, and adjust some pointer according to the implementation requirement so that the node can be found when the key is specified and when the map itself is walked by iterators.

The creation / deletion of nodes happens through an instance of a std::allocator, by calling allocate and by calling a placement new on the returned space.
Vice versa, deletion is made by explicitly calling the node destructor, and then calling the allocator deallocate giving the memory back to it.

The purpose of atd::allocator is to allocate/deallocate uninitialized memory. The default implementation (used by std::map, if you don't specify anything else for it) is to allocate a chunk of bytes as a char[] using new char[x], and returning tham to the system via delete[].

Respect to your operator new, there is no "global" or "local" "overload".
void* operator new(size_t) is nothing more than a function whose prototype is declared in <new> and whose compiled body is placed into the C runtime library that is linked by default.

What you do is just provideng another implementation of that same function prototype into an OBJ file the linker will resolve before going to the default library. Hence the default library function is not anymore visible, and whatever compiled code (including the instance of the STL templates, since they instantiate into you own translation units) will refer to your function.

The point, now, is to make sure that you provided consistent and congruent overload for both
void* oeprator new(size_t)

and
void* operator new[](size_t)

since i may be you override one and the STL implementation is calling the other.

You also should override the correspondent
void operator  delete(void*)

and
void operator delete[](void*)


It's not -in general- a good practice to overload the global new/delete (since it can lead to conflicts between libraries).
Consider a different syntax like the one you can obtain with
enum my_new_t { my_new };
void* operator new(size_t sz, my_new_t)
{
   //your own stuff
   return ::operator new(sz);
}

that can be used as
A* pa = new(my_new)A;

That's clearly different that new A or new(hes_new)A.
An if you need another allocation scheme for STL classes, consider to write your own allocator class.
 
Share this answer
 
Comments
Member 8576081 17-Feb-12 0:25am    
I understood what you said..But as I mentioned before as well that I am developing a memory leak detector ..so the calls to new will be in the user's code and I wont have any control over the syntax he might use. His call to new/delete will be guided to the overloaded new/delete where the information about the new/delete call will be extracted. Now can you please suggest !anything.
Emilio Garavaglia 17-Feb-12 2:19am    
The safest way is to declare all the operator new and operator delete variants you can find in <new> as inline function in one of your header and make sure your header is always included before any other. This will bypass whatever compiled version exist in whatever library.

Of course, your inlined version may just call regular function you can supp,ly in other modules.
In this way, whatever translation unit will not see your header will use the library one, otherwise your one.

But since STL containers are templates (and hence defined inline), STL will use both your function or the library ones depending if the CPP file you are compiling includes or not your header.
Stefan_Lang 17-Feb-12 10:58am    
Instead of putting your own implementations of new and delete in the global namespace, put them in a namespace of your own. These will be separate from the standard implementations, and you will be able to use either.

You can then add a using statement in a central header of your application, so that all of your own code uses yor own versions instead of the standard ones.

Then you write an allocator class that calls the global new, using ::new() (and similar for deallocate), and pass that class as a template parameter to std::map, as CPallini explained in his solution.

That should enable you to use the standard new/delete for std::map and your own implementation for everything else.
Have a look at Visual Leak Detector - Enhanced Memory Leak Detection for Visual C++[^]

The latest version is located at http://vld.codeplex.com/[^]

Why are you creating a memory leak detector?

Have you considered using shared_ptr[^] to manage your dynamically allocated objects?

Best regards
Espen Harlinn
 
Share this answer
 
Member 8576081 wrote:
can anyone tell me how does stl's map.insert() works?
The documentation[^] can. You have control on the allocator the map will use, it is the fourth (the second optional) template paramenter in the map declaration.
 
Share this answer
 
I Think map.insert calls the Copy constructor and not the main constructor. so perhaps you could write a copy constructor to check if it is still calling the overloaded new or global new.

One another dirty way of doing it could be:

C++
<br />
MyObject *obj = new Myobject();  //this will call the overloaded new, lets not insert this in map.<br />
<br />
Myobject *object = ::new MyObject(); //this will call the global new.<br />
map.insert(*object);<br />

I am not sure if it will help as the problem could be in the logic i.e. why do we need this behavior?

Tell me if my idea worked as i m not very confidant on it.

[BUT there is a problem too, who will do the delete for these news. perhaps copy constructor should anyways be required to perform deep copy to ensure the map wont kill our objects while killing its elements ]
 
Share this answer
 
v2
In simple words, I just want that when map.insert calls the new operator it should call the global new and not the overloaded new? Is that possible?
 
Share this answer
 
Any suggestions if crtsetallochook can help?
 
Share this answer
 
v2
Comments
Member 8576081 6-Apr-12 2:51am    
...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900