問題priority_queue書きのメモリ後のヒープ
-
18-09-2019 - |
質問
私は利用しようと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);
に < キュー>
:(
この定義のメッセージのクラスで非常にシンプルです:
#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-メッセージ
解決
私はこの問題は、あなたのMessage
オブジェクトはその後、割り当て解除得ている生のC文字列へのポインタを維持しているということだと思います。これらの行でます:
cin >> str;
Message p(str.c_str(), rand()%12);
あなたの古いメッセージは、データを無効に向いているように、ループの各反復では、あなたは、そのstr
メソッドから返された古いポインタを無効にc_str()
する新しい値に読んでいます。それは代わりにMessage
のstd::string
としてその文字列を格納するようにあなたのchar*
オブジェクトを変更する必要があります。これは、適切にMessage
オブジェクトに文字列をコピーします。
Message
クラスを変更できない場合は、あるいは、あなたは明示的に、例えば、文字列を自分でコピーする必要がありますstrdup()
またはmalloc()
/ new[]
+ strcpy()
を使用して、あなたには、いくつかの後の時点で、文字列のコピーの割り当てを解除することを忘れないようにしています。
他のヒント
私が取得できない事を確認してください。
があるわけではありません十分な情報をコンパイルこのライン:
push_heap(c.begin(), c.end(), comp);
ものだけを問題に見えるのは:
1)においてデフォルトのコンストラクタをPoruka 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::stringクラスです。
- だいchar*その場合は保証ということはありませんNULLの場合、コードが簡単になり
- また、簡単な模様を定義するための、標準コピーコンストラクタと代入演算子です。であると考としてコピー/スワップidium.
- だが必要になりすべての関係。セットがありますので、自分でテンプレートを自動的に見 http://www.sgi.com/tech/stl/operators.html.だけを定義するオペレーター< およびオペレーター==
この例では、コピー/スワップ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);
}