Pregunta

Estoy tratando de utilizar priority_queue, y el programa falla constantemente con CORRUPCIÓN mensaje de error de memoria montón detectada.

aquí están los fragmentos:

class CQueue { ...
              priority_queue<Message, deque<Message>, less<deque<Message>::value_type> > m_messages;
...};

clase de mensaje se ha sobrecargado los operadores> y <

Aquí cumplo cola:

CQueue & operator+=(Message &rhv)
{
    m_messages.push(rhv);  //This is where program fails
    return *this;
}

y en el programa principal:

string str;
CQueue pq;
for(int i = 0; i < 12; ++i)
{
    cin >> str;

    Message p(str.c_str(), rand()%12); //Create message with random priority
    pq += p;                           //add it to queue
}

No tengo idea de lo que parece ser el problema. Sucede cuando empujo alrededor de 8 artículos, y falla en la línea

    push_heap(c.begin(), c.end(), comp);

en

: (

Esta es la definición de clase de mensaje - Es muy simple:

#pragma once 

#include <iostream>
#include <cstring>
#include <utility>

using namespace std;

 class Poruka
{
private:
char *m_tekst;
int  m_prioritet;
public:
Poruka():m_tekst(NULL), m_prioritet(-1){}

Poruka(const char* tekst, const int prioritet)
{
    if(NULL != tekst)
    {
    //  try{
            m_tekst = new char[strlen(tekst) + 1];
        //}
        //catch(bad_alloc&)
    //  {
    //      throw;
    //  }


        strcpy(m_tekst, tekst);
    }
    else
    { 
    //  try
    //  {
            m_tekst = new char[1];
    //  }
    //  catch(bad_alloc&)
    //  {
    //      throw;
    //  }

        m_tekst[0] = '\0';
    }
    m_prioritet = prioritet;
}

Poruka(const Poruka &p)
{
    if(p.m_tekst != NULL)
    {
        //try
        //{
            m_tekst = new char[strlen(p.m_tekst) + 1];
        //}
        //catch(bad_alloc&)
        //{
        //  throw;
        //}

        strcpy(m_tekst, p.m_tekst);
    }
    else
    {
        m_tekst = NULL;
    }
    m_prioritet = p.m_prioritet;
}

~Poruka()
{
        delete [] m_tekst;
}

Poruka& operator=(const Poruka& rhv)
{
    if(&rhv != this)
    {
        if(m_tekst != NULL)
            delete [] m_tekst;

    //  try
        //{
            m_tekst = new char[strlen(rhv.m_tekst + 1)];
        //}
        //catch(bad_alloc&)
        //{
        //  throw;
        //}

        strcpy(m_tekst, rhv.m_tekst);
        m_prioritet = rhv.m_prioritet;
    }
    return *this;
}

friend ostream& operator<<(ostream& it, const Poruka &p)
{
    it << '[' << p.m_tekst << ']' << p.m_prioritet;
    return it;
}

//Relacioni operatori

friend inline bool operator<(const Poruka& p1, const Poruka& p2)
{
    return p1.m_prioritet < p2.m_prioritet;
}

friend inline bool operator>(const Poruka& p1, const Poruka& p2)
{
    return p2 < p1;
}

friend inline bool operator>=(const Poruka& p1, const Poruka& p2)
{
    return !(p1 < p2);
}

friend inline bool operator<=(const Poruka& p1, const Poruka& p2)
{
    return !(p1 > p2);
}

friend inline bool operator==(const Poruka& p1, const Poruka& p2)
{
    return (!(p1 < p2) && !(p2 < p1));
}

friend inline bool operator!=(const Poruka& p1, const Poruka& p2)
{
    return (p1 < p2) || (p2 < p1);
}

};

Poruka - Mensaje

¿Fue útil?

Solución

Creo que el problema es que sus objetos Message mantienen punteros a cadenas de C primas que están a continuación, obtener desasignan. En estas líneas:

cin >> str;

Message p(str.c_str(), rand()%12);

En cada iteración del bucle, que está leyendo en un nuevo valor a str, lo que invalida cualquier puntero viejos devueltos por su método c_str(), por lo que sus mensajes más antiguos están apuntando a datos no válidos. Debe cambiar su objeto Message para que almacene su cadena como un std::string en lugar de un char*. Esto copiará correctamente la cadena en un objeto Message.

Como alternativa, si no se puede cambiar la clase Message, tendrá que copiar explícitamente la cadena de sí mismo, por ejemplo, utilizando strdup() o malloc() / new[] + strcpy(), y entonces usted tiene que acordarse de cancelar la asignación de las copias de cuerda en algún momento posterior.

Otros consejos

No puedo hacer que falle.
Sin embargo, no hay suficiente información para compilar esta línea:

push_heap(c.begin(), c.end(), comp);

Sin embargo, los únicos problemas que veo son:

1) Usted tiene un constructor por defecto que pudiera crear un Poruka con un nombre NULL:

Poruka::Poruka():m_tekst(NULL), m_prioritet(-1){}

2) No es un problema, ya que las pruebas correspondientes mayoría de los lugares, pero en el operador de asignación se le pasa una prueba:

Poruka::Poruka& operator=(const Poruka& rhv)
{
 ....
    // There was no test for 'rhv.m_tekst' being NULL here.
    //
    m_tekst = new char[strlen(rhv.m_tekst + 1)];
    strcpy(m_tekst, rhv.m_tekst);

Notas:

  • Se podría hacer que el código mucho más simple mediante el uso de la clase std :: string.
  • Si aún desea utilizar char * a continuación, si gurantee nunca es NULL, el código es más simple
  • También hay un golpeteo más simple para definir el constructor de copia y asignación del operador estándar. Se refiere a que la copia / idium intercambio.
  • Usted no necesita definir todos aquellos operadores relacionales. Hay un conjunto de las plantillas que trabajan de forma automática en la página http: //www.sgi. com / tecnología / STL / operators.html . Sólo tiene que definir el operador <== y el operador

Aquí es un ejemplo de la copia idium / intercambio

class X
{
     X(X const& copy)
     {
          // Do the work of copying the object
          m_tekst     = new char[strlen(copy.m_tekst) + 1];
          ...
          m_prioritet = copy.m_prioritet;
     }
     X& operator=(X const& copy)
     {
         // I like the explicit copy as it is easier to read
         // than the implicit copy used by some people (not mentioning names litb)
         //
         X  tmp(copy);  // Use the copy constructor to do the work

         swap(tmp);
     }
     void swap(X& rhs) throws ()
     {
         std::swap(this->m_tekst,   rhs.m_tekst);
         std::swap(this->prioritet, rhs.prioritet);
     }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top