简体   繁体   English

调试断言失败... _BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)

[英]Debug Assertion Failed … _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

I have got a really bad memory leak I am trying to fix, but somehow i am not able to delete Objects without triggering this assertation. 我有一个非常糟糕的内存泄漏,我试图修复,但不知何故,我不能删除对象而不触发此断言。

I have searched for a solution via Google and have read the Questions on stackoverflow about this Error but I was still not able to find the answer! 我已经通过谷歌搜索了一个解决方案并已阅读有关此错误的有关stackoverflow的问题,但我仍然无法找到答案!

Possible reasons to get this Error according to my research: 根据我的研究得出此错误的可能原因:
1. deleting objects more then one 1.删​​除多个对象
2. shadow copying 2.影子复制
3. creating and deleting Objects that are loaded from an external dll 3.创建和删除从外部DLL加载的对象
4. creating objects without storing the pointer 4.在不存储指针的情况下创建对象

BUT: 但:
1. I checked the code and was not able to find double deletion 我检查了代码,但未能找到双重删除
2. I use a copy constructor to copy Objects 2.我使用复制构造函数来复制对象
3. The Error relatet classes are build (with MS Visual Studio) to a seperate lib but not to a dll. 3.错误的关联类是建立(使用MS Visual Studio)到单独的lib而不是dll。 AND all the classes that are related to this error are located in the same lib. 并且与此错误相关的所有类都位于同一个lib中。
4. I checked the code and it seems like that's not the problem 我检查了代码,看起来这不是问题

It would be great if anybody is able to spot the mistake in the code below, and I appreciate every hint that points me to the solution of the problem. 如果有人能够在下面的代码中发现错误,那将是很好的,我感谢每一个指示我解决问题的提示。

EDIT: 编辑:
I forgot to mention the same deleting problem in sendThreadMain of MessageSystem (see code below). 我忘了在MessageSystem的sendThreadMain中提到相同的删除问题(参见下面的代码)。 If i delete the Message there it causes unexpected errors somewhere else in the code. 如果我删除消息,它会在代码中的其他地方导致意外错误。 Might just be wrong data transmission... but i do not really know. 可能只是错误的数据传输......但我真的不知道。
This code is run on Windows and Linux! 此代码在Windows和Linux上运行!

Here are the error related parts of the code: 以下是代码的错误相关部分:

Message 信息

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::~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 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

Today I figured it out on my own. 今天我自己想出来了。 It was #1 of the 4 possibilities mentioned in the Question. 它是问题中提到的4种可能性中的第1种。

  1. deleting objects more then once (by saving multiple pointers to the exact same object) 多次删除对象(通过将多个指针保存到完全相同的对象)

Here is my Solution in MessageQueue: 这是我在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);
    }
}

Well, I faced similar problem, the following code 好吧,我遇到了类似的问题,下面的代码

Message* message = messageQueue.front ();
messageQueue.pop_front();

return message;

The code that produced error with me was: 与我产生错误的代码是:

Point *p = q.LookFor(&q, &pts[5], &Dist);
cout ...
delete p;

It seems that the function delete the pointer it creates in the runtime, so you're not allowed to delete it "again" 似乎该函数删除了它在运行时创建的指针,因此不允许“再次”删除它

so I replaced it with 所以我换了

Point p = *(q.LookFor(&q, &pts[5], &Dist));

and it's gone. 它已经消失了。

It might be a simple problem of wrong order. 这可能是错误订单的简单问题。 You are doing: 你在做:

while(messageQueue.size() > 0)
{
    delete messageQueue.front();
    messageQueue.pop_front();
}

Maybe deleting the message after popping it, instead of before, would do the trick: 也许在弹出消息之后删除消息,而不是之前,可以做到这一点:

while(messageQueue.size() > 0)
{
    Message* pFront = messageQueue.front();
    messageQueue.pop_front();
    delete pFront;
}

Anyway, I am not confident at all on this solution, since deleting the object pointed by pFront should have no effect on the queue itself, which just stores pointers. 无论如何,我对此解决方案一点也不自信,因为删除pFront指向的对象应该对队列本身没有影响,队列本身只存储指针。 But you can try. 但你可以试试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 调试断言失败_BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse) - Debug Assertion Failed _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 此代码有什么问题? 为什么显示:调试断言失败! _BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse)? - What is the trouble with this code? Why is it showing: Debug assertion failed! _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)? 调试断言失败! 表达式:_BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse)在程序结束 - Debug Assertion Failed! Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) In program ended 来自Deconstructor的调试断言失败BLOCK_TYPE_IS_VALID(pHead-&gt; nblockuse) - Debug assertion failed BLOCK_TYPE_IS_VALID(pHead->nblockuse) from Deconstructor 调试断言失败! 表达式:_BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse) - Debug Assertion Failed! Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) _block_type_is_valid(phead-nblockuse)由于删除命令 - _block_type_is_valid(phead- nblockuse) because of delete command 表达式_BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse)错误 - Expression _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) Error 错误-_BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse) - Error - _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) _BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse)在C ++中崩溃 - _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) crash in C++ “返回0”后__BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse) - _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) after “return 0”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM