Std :: bad placement error map

I have a problem with std :: map. For unknown reasons, sometimes inserting onto a card results in the exclusion of "poor distribution."

Below is the function that I use to insert into the card.

BOOL Add2WaitList(Object<LPVOID> *newObj) { try { _set_se_translator( trans_func ); m_syncWQ.Lock(); if (m_waitingQueue.count(newObj->uid)>0) { m_syncWQ.Unlock(); return FALSE; } m_waitingQueue[newObj->uid] = *newObj; <-- failing here m_syncWQ.Unlock(); return TRUE; } catch(std::exception &ex){ ... } catch(SE_Exception &e){ ... } catch(...){ ... } } 

Can someone tell me how to solve this?

NOTE. I cannot identify the steps for playing it.

thanks in advance!

Adding object and map information:

 template <typename T> struct Object{ public: void Kill() { if (response!=NULL) delete response; if (object!=NULL) delete object; } enum objType; std::string uid; enum status; double p; enum execType; T object; LPVOID response; }; std::map<std::string,Object<LPVOID>> m_waitingQueue; 
+4
source share
4 answers

The exception std::bad_alloc means " operator new failed". Thus, either operator new receives a call to operator* on newObj (which we don’t know anything about), or a map insert operator (which is more likely).

In particular, when you call operator[] on a map with some parameter k

If k does not match the key of any element in the container, the function inserts a new element with this key and returns a link to its displayed value. Please note that this always increases the container size by one, even if the item has no associated value (the item is created using its default constructor).

(as described here ).

Map::operator[] provides a reliable failure guarantee:

 Strong guarantee: if an exception is thrown, there are no changes in the container. 

but does not guarantee that the exception will not be thrown (i.e., it does not guarantee the absence of failure).

The reason operator new throwing exceptions can be of a different nature. However, it all boils down to:

 throws bad_alloc if it fails to allocate storage. 

However, as James Canze says in the comments:

Another possible reason for std :: bad_alloc is undefined behavior. If for example, he ruined the arena of free space. And realistic, if he really runs out of memory, the distribution where it fails will be different. If systematically here, I would suspect a problem in the constructor of copying an object, more than anything else.

means that operator new cannot allocate storage due to some error in other parts of the program. You can debug your null information (as statistics called it) by allocating (very) large amounts of data immediately before calling operator[] . If the dummy distribution does not work, you can say that the error with the copy constructor is with good certainty.

+2
source

Obviously std :: map operation is causing the problem

 m_waitingQueue[newObj->uid] = *newObj; 

This is actually a card insert operation that could allocate memory behind the scene: How is the STL card allocated? Stack or Heap? . One possible reason is that allocating memory results in a "Bad Allocation" exception : Exceptions for exception in C ++ .

But this code alone does not lead to an explanation of what happens behind the scenes. I think that additional information is needed regarding the "m_waitingQueue", since the variable is global, which can be done outside of this function.

+2
source

The operator new() function cannot find the requested memory. This function can be called from the new expression or directly in the std::map distributor.

You do not provide any information regarding the context. the real question is: does this always happen at this particular point. If you really ran out of memory (for example, due to a memory leak), you would expect it to hit other distributions, like Well. Other possibilities are that you are in the space arena before calling this function or there is a problem with the Object<LPVOID> copy constructor, which forces it to request unlimited memory or the free space arena, so the next allocation is not performed. Did you copy this object to another location? The fact that you pass in its pointer suggests that it may not, in which case it will be where you see the problem.

EDIT:

Since you posted the code for Object : where is the Object you are using the source? And what do pointers usually indicate, and if it is dynamically allocated, how are managed ones removed?

Because Object does not have user-defined constructors, which means that there will be times when pointers contain random garbage. And deleting random pointers is a very good way to ruin the arena of free space.

Also: I noticed that you have synchronization of primitives ( Lock() and Unlock() ). Where else is m_waitingQueue used? If m_waitingQueue can be accessed from another thread, all calls to m_waitingQueue must be synchronized using the same synchronization object ( m_syncWQ ). Trying to change m_waitingQueue to another thread while you change it, can also lead to undefined (with recording the object in the queue where it should not have been).

0
source

Perhaps Add2WaitList(Object<LPVOID>) simply called millions of times until memory runs out.

In this case, the reason lies elsewhere in the code β€” for example, as an infinite loop or regression. Another possible reason could be if your Object inadvertently changes everything uid s. This can happen if the uid obtained from an uninitialized number, for example.

0
source

Source: https://habr.com/ru/post/1492243/


All Articles