问题符写的存储器之后堆
-
18-09-2019 - |
题
我正尝试使用符和程序不断失败的错误信息堆损坏检测。
这段:
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则的代码是简单
- 还有更简单的模式用于确定标准的复制构造和分配运营商。它被称为复制/交换伊德石.
- 你不需要定义的所有那些关系的运营商。有一组模板的自动工作中看到 http://www.sgi.com/tech/stl/operators.html.你只需要确定操作者< 和操作员==
这里是一个例子副本/交换伊德石
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);
}
不隶属于 StackOverflow