Ho una perdita di memoria veramente brutta che sto cercando di risolvere, ma in qualche modo non sono in grado di eliminare gli oggetti senza attivare questa asserzione.Assunzioni di debug non riuscite ... _BLOCK_TYPE_IS_VALID (pHead-> nBlockUse)
Ho cercato una soluzione tramite Google e ho letto le domande su StackOverflow su questo errore ma non ero ancora in grado di trovare la risposta!
possibili ragioni per ottenere questo errore secondo la mia ricerca: oggetti
1. eliminazione più di un
2. ombra copia
3. Creazione ed eliminazione di oggetti che vengono caricati da una DLL esterna
4. creazione gli oggetti senza memorizzare il puntatore
MA:
1. ho controllato il codice e non sono riuscito a trovare doppia eliminazione
2. io uso un costruttore di copia per copiare gli oggetti
3. Le classi di relatet Error sono compilate (con MS Visual Studio) in una lib separata ma non in una DLL. E tutte le classi correlate a questo errore si trovano nella stessa lib.
4. Ho controllato il codice e sembra che non è questo il problema
Sarebbe bello se qualcuno è in grado di individuare l'errore nel codice qui sotto, e mi rendo conto ogni suggerimento che mi punta alla soluzione del problema.
MODIFICA:
Ho dimenticato di menzionare lo stesso problema di eliminazione in sendThreadMain di MessageSystem (vedere il codice seguente). Se elimini il messaggio lì causa errori imprevisti da qualche altra parte nel codice. Potrebbe essere solo una trasmissione dati sbagliata ... ma non lo so davvero.
Questo codice è eseguito su Windows e Linux!
Ecco l'errore relativi parti del codice:
Messaggio
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
Non si aggiungono messaggi alla coda in nessun altro posto rispetto alla funzione 'broadcast'? –
Ci sono buone notizie e cattive notizie. La buona notizia è che questo sicuramente non è causato da una perdita di memoria. –
Non sono sicuro se questo è il problema ma dovresti avere un distruttore virtuale nella classe Message. –