调试断言失败... _BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)
我有一个非常糟糕的内存泄漏,我试图修复,但不知何故,我无法删除对象,而没有触发这个断言。调试断言失败... _BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)
我已经通过Google搜索了一个解决方案,并阅读了有关此错误的*问题,但我仍然无法找到答案!
可能的原因,根据我的研究,出现此错误:
1.删除对象不止一个
2.影子复制
3.创建和删除是从外部的dll加载的对象
4.创建对象不存储指针
但是:
1.我检查了代码,没能找到双缺失
2.我用一个拷贝构造函数来复制对象
3.错误关联类是建立(与MS Visual Studio)到一个单独的库,但不是一个DLL。并且与此错误相关的所有类都位于同一个库中。
4.我检查了代码,它似乎不是问题
如果有人能够发现下面的代码中的错误,这将是非常好的,我感谢每一个提示,指出我的解决方案问题。
编辑:
我忘了提及MessageSystem的sendThreadMain(请参阅下面的代码)中相同的删除问题。如果我在那里删除消息,它会在代码中的其他地方导致意外的错误。可能只是错误的数据传输......但我不知道。
此代码在Windows和Linux上运行!
下面是相关的部分代码错误:
消息
class Message
{
public:
Message (char type, unsigned char id, unsigned short size)
{
mType = type;
mId = id;
mSize= size;
}
Message(const Message &o)
{
mType = o.mType;
mId = o.mId;
mSize = o.mSize;
}
char getType() const {return mType;};
unsigned char getId() const {return mId;};
unsigned short getSize() const {return mSize;};
protected:
char mType;
unsigned char mId;
unsigned short mSize;
};
class JoinMessage : public Message
{
public:
JoinMessage() : Message ('j', 0, sizeof (JoinMessage))
{
team = TEAM_SPECTATOR;
}
JoinMessage (unsigned char id) : Message ('j', id, sizeof (JoinMessage)){}
JoinMessage (const JoinMessage &o) : Message (o)
{
team = o.team;
setName(o.getName());
}
void setName(std::string newName)
{
if (newName.length() > MAX_PLAYER_NAME_LENGHT)
newName = newName.substr(0, MAX_PLAYER_NAME_LENGHT);
memset(name, 0, MAX_PLAYER_NAME_LENGHT);
for(unsigned int i = 0; i < newName.length(); i++)
name[i] = newName[i];
}
std::string getName() const
{
std::string stringToReturn;
for(unsigned int i = 0; i < MAX_PLAYER_NAME_LENGHT; i++)
{
if (name[i])
stringToReturn.push_back(name[i]);
else
break;
}
return stringToReturn;
}
TeamIdentifier team;
private:
unsigned char name[MAX_PLAYER_NAME_LENGHT];
};
// there are a lot other messages
的MessageQueue
MessageQueue::~MessageQueue()
{
boost::mutex::scoped_lock lock (queueMutex);
while(messageQueue.size() > 0)
{
// the crash is non-reproducible
// works 90% of the time
delete messageQueue.front(); // <- Debug Assertion Failed … _BLOCK_TYPE_IS_VALID
messageQueue.pop_front();
}
}
void MessageQueue::enqueMessage (Message* message)
{
{
boost::mutex::scoped_lock lock (queueMutex);
messageQueue.push_back(message);
}
}
Message* MessageQueue::dequeMessage()
{
boost::mutex::scoped_lock lock (queueMutex);
if (messageQueue.size() == 0)
return nullptr;
Message* message = messageQueue.front();
messageQueue.pop_front();
return message;
}
MessageSystem
template <class MessageType>
void broadcast (MessageType &message)
{
MessageType *internMessage = new MessageType(message);
boost::mutex::scoped_lock lock (mRecipientMapMutex);
std::map <boost::asio::ip::udp::endpoint, MessageQueue *>::iterator it;
for (it = mRecipientMap.begin();
it != mRecipientMap.end();
it++)
{
it->second->enqueMessage(internMessage);
}
}
template <class MessageType>
void post (MessageType &message, boost::asio::ip::udp::endpoint &recipient)
{
MessageType *internMessage = new MessageType(message);
std::map <boost::asio::ip::udp::endpoint, MessageQueue* >::iterator it;
MessageQueue *messageQueue = NULL;
{
boost::mutex::scoped_lock lock (mRecipientMapMutex);
it = mRecipientMap.find (recipient);
if (it != mRecipientMap.end())
messageQueue = it->second;
if(messageQueue)
messageQueue->enqueMessage (internMessage);
}
}
void MessageSystem::sendThreadMain()
{
// copy endpoints to vecotr so it can be
// deleted from map while iterating
std::vector<udp::endpoint> endpoints;
{
boost::mutex::scoped_lock lock (mRecipientMapMutex);
std::map <udp::endpoint, MessageQueue *>::iterator mapIt = mRecipientMap.begin();
while (mapIt != mRecipientMap.end())
{
endpoints.push_back(mapIt->first);
mapIt++;
}
}
std::vector<udp::endpoint>::iterator endpointIt = endpoints.begin();
while (endpointIt != endpoints.end())
{
char sendBuffer[PACKET_SIZE];
int sendBufferPosition = 0;
{
boost::mutex::scoped_lock lock (mRecipientMapMutex);
MessageQueue *messageQueue = mRecipientMap[*endpointIt];
if (messageQueue == nullptr)
{
mRecipientMap.erase(*endpointIt);
endpointIt++;
continue;
}
while (Message *message = messageQueue->dequeMessage())
{
if (sendBufferPosition + message->getSize() > PACKET_SIZE)
{
// put message back and send it later
messageQueue->enqueMessage (message);
break;
}
// copy message into buffer
std::memcpy (
&sendBuffer [sendBufferPosition], message, message->getSize());
sendBufferPosition += message->getSize();
// deleting this message causes a crash if 2 or more
// recipients are registered within MessageSystem
//delete message; <- RANDOM CRASH elsewhere in the program
}
}
.... // more code down here that seems not related to the error
今天我想到了我自己。这是问题中提到的4种可能性中的第一种。
- 删除对象,曾多次(通过保存多个指针,以完全相同的对象)
这是我在的MessageQueue解决方法:
template <class MessageType>
void broadcast (MessageType &message)
{
// I was creating 1 new Message right here but I need 1 new Message
// in EVERY MessageQueue so i moved the next line ...
// MessageType *internMessage = new MessageType(message);
boost::mutex::scoped_lock lock (mRecipientMapMutex);
std::map <boost::asio::ip::udp::endpoint, MessageQueue *>::iterator it;
for (it = mRecipientMap.begin();
it != mRecipientMap.end();
it++)
{
// ... down here. Now every queue contains its own copy of the Message
MessageType *internMessage = new MessageType(message);
it->second->enqueMessage(internMessage);
}
}
这可能是一个简单的亲错误顺序的瑕疵。你正在做的:
while(messageQueue.size() > 0)
{
delete messageQueue.front();
messageQueue.pop_front();
}
也许删除消息弹出之后,而不是之前,会做的伎俩:
while(messageQueue.size() > 0)
{
Message* pFront = messageQueue.front();
messageQueue.pop_front();
delete pFront;
}
反正我根本没有信心在这个解决方案,因为删除由pFront
指向的对象应该对队列本身没有影响,它只存储指针。但你可以试试。
我也认为它应该对队列没有任何影响,但我会尽力去做。但它似乎是另一个问题,因为从队列中删除消息后删除消息不起作用(请参阅MessageSystem末尾的while循环) – cwin
好吧,我面临着类似的问题, 以下代码
Message* message = messageQueue.front();
messageQueue.pop_front();
return message;
The与我产生的错误代码是:
Point *p = q.LookFor(&q, &pts[5], &Dist);
cout ...
delete p;
看来这个函数删除它会在运行时的指针,所以你不能删除“再次”
,所以我用它代替
Point p = *(q.LookFor(&q, &pts[5], &Dist));
它消失了。
您不会将消息添加到除'broadcast'功能以外的任何其他位置的队列吗? –
有好消息和坏消息。好消息是,这绝对不是由内存泄漏造成的。 –
我不确定这是否是问题,但是您应该在类Message中拥有虚拟析构函数。 – 2011-12-02 10:35:22