문제

Priority_queue를 사용하려고 노력하고 있으며 오류 메시지 힙 손상이 감지 된 상태에서 프로그램이 지속적으로 실패합니다.

스 니펫은 다음과 같습니다.

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

클래스 메시지는 연산자를 과부하 시켰습니다

여기서 나는 대기열을 채 웁니다.

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

그리고 주요 프로그램에서 :

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
}

나는 문제가 무엇인지 전혀 모른다. 약 8 개 항목을 푸시 할 때 발생하며 라인에서 실패합니다.

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

<queue>에서

:(

다음은 메시지 클래스의 정의입니다. 매우 간단합니다.

#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);
}

};

포루카 - 메시지

도움이 되었습니까?

해결책

나는 문제가 당신의 것입니다 Message 객체는 포인터를 원시 C 줄로 유지 한 다음 거래가 발생합니다. 이 라인에서 :

cin >> str;

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

루프의 각 반복에서 새로운 가치로 읽고 있습니다. str, 그것은 그것에 의해 반환 된 오래된 포인터를 무효화합니다 c_str() 방법, 이전 메시지가 유효하지 않은 데이터를 가리키고 있습니다. 당신은 당신의 것을 바꿔야합니다 Message 문자열을 an으로 저장하도록 객체 std::string 대신 a char*. 이것은 문자열을 올바르게 복사합니다 Message 물체.

또는 변경할 수없는 경우 Message 클래스, 당신은 당신은 string을 명시 적으로 복사해야합니다. strdup() 또는 malloc()/new[]+strcpy(), 그런 다음 나중에 문자열 사본을 처리해야합니다.

다른 팁

실패 할 수 없습니다.
그러나이 줄을 컴파일하기에 충분한 정보가 없습니다.

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

그러나 내가 보는 유일한 문제는 다음과 같습니다.

1) 당신은 null 이름의 포루 카를 만들 수있는 기본 생성자가 있습니다.

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

2) 대부분의 장소를 테스트하기 때문에 문제가되지 않지만 과제 연산자에서는 테스트를 놓치고 있습니다.

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);

메모:

  • std :: 문자열 클래스를 사용하여 코드를 훨씬 간단하게 만들 수 있습니다.
  • 여전히 char*를 사용하고 싶다면 gurantee가 null이되지 않으면 코드가 더 간단합니다.
  • 또한 표준 카피 생성자 및 할당 연산자를 정의하기위한 더 간단한 패턴이 있습니다. 그것은 사본/스왑 idium이라고합니다.
  • 모든 관계형 운영자를 정의 할 필요는 없습니다. 자동으로 작동하는 템플릿 세트가 있습니다. http://www.sgi.com/tech/stl/operators.html. 연산자를 정의하면 <and operator ==

다음은 사본/스왑 idium의 예입니다.

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);
     }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top