Tengo una muy mala pérdida de memoria que estoy tratando de corregir, pero de alguna manera no puedo eliminar Objetos sin desencadenar esta afirmación.Confirmación de depuración Falló ... _BLOCK_TYPE_IS_VALID (pHead-> nBlockUse)
He buscado una solución a través de Google y he leído las Preguntas sobre stackoverflow sobre este Error pero todavía no he podido encontrar la respuesta.
razones posibles para conseguir este error de acuerdo a mi investigación: Objetos
1. borrar más de un
2. copia sombra
3. Creación y eliminación de objetos que se cargan desde una DLL externa
4. Crear objetos sin almacenar el puntero
PERO:
1. he comprobado el código y no era capaz de encontrar deleción doble
2. utilizo un constructor de copia para copiar objetos
3. Las clases de relaate de error se compilan (con MS Visual Studio) en una lib separada, pero no en una dll. Y todas las clases que están relacionadas con este error se encuentran en la misma lib.
4. he comprobado el código y parece que ese no es el problema
Sería muy bueno si alguien es capaz de detectar el error en el código de abajo, y aprecio cada pista que me apunta a la solución del problema.
EDIT:
Se me olvidó mencionar el mismo problema de eliminación en sendThreadMain de MessageSystem (ver código a continuación). Si elimino el mensaje allí, causa errores inesperados en otro lugar en el código. Podría ser una transmisión de datos errónea ... pero realmente no lo sé.
¡Este código se ejecuta en Windows y Linux!
Aquí están los errores relacionados con partes del código:
mensaje
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
No agrega mensajes a la cola en ningún otro lugar que la función 'broadcast'? –
Hay buenas y malas noticias. La buena noticia es que esto definitivamente no es causado por una pérdida de memoria. –
No estoy seguro de si este es el problema, pero debería tener un destructor virtual en la clase Mensaje. –