我正面临着std :: map的问题。由于未知原因,有时插入映射会导致“错误分配”异常。
以下是我用于插入地图的功能。
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(...){
...
}
}
有人可以告诉我如何解决这个问题吗?
注意:我无法确定重现它的步骤。
提前THX!添加有关Object&amp;的详细信息图:
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;
答案 0 :(得分:2)
例外std::bad_alloc
表示“operator new
失败”。因此,operator new
在operator*
(我们对此一无所知)或地图的插入运算符(这种情况极有可能)被调用newObj
。
具体而言,当您使用某个参数k
在地图上调用operator[]
时
如果k与容器中任何元素的键不匹配,则 function使用该键插入一个新元素并返回一个引用 到它的映射值。请注意,这总是会增加容器 即使没有为元素分配映射值,也将大小加1 element是使用其默认构造函数构造的。
(如记录here)。
Map::operator[]
为失败提供了强有力的保证:
Strong guarantee: if an exception is thrown, there are no changes in the container.
但不保证不会抛出异常(即它不提供无抛出保证)。
operator new
抛出异常的原因可能不同。但是,这一切归结为:
throws bad_alloc if it fails to allocate storage.
那就是说,正如JamesKanze在评论中所说:
std :: bad_alloc的另一个可能原因是未定义的行为。如果 例如,他摧毁了自由空间舞台。而且实际上, 如果他真的耗尽内存,那么失败的分配 会有所不同如果系统地在这里,我会怀疑有问题 Object的复制构造函数,最重要的是。
意味着operator new
由于程序其他部分的某些错误而无法分配存储空间。你可以通过在调用operator[]
之前分配一个(非常)大数据块来调试他的null-assupmtion(统计学家会调用它)。如果虚拟分配没有失败,您可以很自信地说复制构造函数中存在错误。
答案 1 :(得分:2)
很明显,std :: map操作会导致问题
m_waitingQueue[newObj->uid] = *newObj;
它实际上是一个地图插入操作,它可能会在场景后面分配内存:How is a STL map allocated? Stack or Heap?。一个可能的原因是将内存导致分配给错误的分配异常:Bad allocation exceptions in C++。
但是这段代码本身并没有导致解释幕后发生的事情。我认为需要更多与“m_waitingQueue”相关的信息,因为变量是全局的,在此函数之外可以做任何事情。
答案 2 :(得分:0)
operator new()
功能无法找到请求的内容
记忆。可以从new
表达式调用此函数,或
直接在std::map
的分配器中。
您不会提供有关上下文的任何信息。该
真正的问题是:它是否总是在这一点上失败。
如果你真的没有内存(例如因为
一个内存泄漏),人们会期望它打到其他分配
好。其他可能性是你破坏了自由
在调用此函数之前的空间竞技场,或者存在
Object<LPVOID>
的复制构造函数的问题
导致它要求无限的内存,或者破坏它
自由空间竞技场,以便下一次分配失败。你呢
将此物品复制到别处你通过它的事实
指针可能不会,在这种情况下,这将是
你会看到问题的地方。
编辑:
由于您已发布Object
的代码:Object
在哪里
你使用originate?指针通常指向什么,
如果它是动态分配的,那么如何管理删除?
因为Object
有没有用户定义的构造函数,这意味着
将存在指针包含随机垃圾的情况。
删除随机指针是腐败的一个很好的方法
自由空间竞技场。
另外:我注意到你看起来像同步
原语(Lock()
和Unlock()
)。还有什么地方
m_waitingQueue
用过了吗?如果可以访问m_waitingQueue
一个不同的线程,所有对m_waitingQueue
的访问必须是
使用相同的同步对象进行同步
(m_syncWQ
)。试图在另一个中修改m_waitingQueue
你在这里修改它时的线程也可能导致
未定义的行为(队列对象在某处写入)
不应该的地方。)
答案 3 :(得分:0)
在内存不足之前,或许Add2WaitList(Object<LPVOID>)
被调用数百万次。
在这种情况下,原因将在代码的其他地方 - 例如以无限循环或回归的形式。另一个可能的原因是,如果您的Object
无意中获得了不同的uid
。例如,uid
从未初始化的数字派生时,可能会发生这种情况。