Priority_queue 问题 - 在堆之后写入内存
我正在尝试使用priority_queue,但程序不断失败,并显示错误消息“HEAP CORRUPTION DETECTED”。
以下是片段:
class CQueue { ...
priority_queue<Message, deque<Message>, less<deque<Message>::value_type> > m_messages;
...};
类 Message 已重载运算符 >且<
在这里我填充队列:
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
}
我不知道问题是什么。 在线失败
push_heap(c.begin(), c.end(), comp);
当我推送大约 8 个项目时,就会发生这种情况,并且在 << 时 。队列>
:(
这是消息类的定义 - 非常简单:
#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 - 消息
I am trying to use priority_queue, and program constantly fails with error message HEAP CORRUPTION DETECTED.
here are the snippets:
class CQueue { ...
priority_queue<Message, deque<Message>, less<deque<Message>::value_type> > m_messages;
...};
class Message has overloaded operators > and <
Here I fill up queue:
CQueue & operator+=(Message &rhv)
{
m_messages.push(rhv); //This is where program fails
return *this;
}
and in the main program:
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
}
I have no idea what seems to be the problem. It happens when I push about 8 items, and it fails on line
push_heap(c.begin(), c.end(), comp);
in < queue >
:(
Here is the definition of message class - it's very 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 - Message
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为问题在于您的
Message
对象保留了指向原始 C 字符串的指针,然后这些字符串被释放。在这些行中:在循环的每次迭代中,您都会向
str
读入一个新值,这会使它的c_str()
方法返回的任何旧指针无效,因此您的旧消息指向无效数据。您应该更改Message
对象,以便将其字符串存储为std::string
而不是char*
。这将正确地将字符串复制到Message
对象中。或者,如果您无法更改
Message
类,则必须自己显式复制字符串,例如使用strdup()
或malloc()< /code>/
new[]
+strcpy()
,然后您必须记住在稍后的某个时刻取消分配字符串副本。I think the problem is that your
Message
objects are keeping pointers to raw C strings which are then getting deallocated. In these lines:On each iteration of the loop, you're reading in a new value to
str
, which invalidates any old pointers returned by itsc_str()
method, so your older messages are pointing to invalid data. You should change yourMessage
object so that it stores its string as anstd::string
instead of achar*
. This will properly copy the string into theMessage
object.Alternatively, if you can't change the
Message
class, you'll have to explicitly copy the string yourself, e.g. usingstrdup()
ormalloc()
/new[]
+strcpy()
, and then you have to remember to deallocate the string copies at some later point.我不能让它失败。
但没有足够的信息来编译这一行:
但我看到的唯一问题是:
1)你有一个默认构造函数,可以创建一个具有 NULL 名称的 Poruka:
2)不是问题,因为你在大多数地方都测试了它,但在您错过了一个测试的赋值运算符:
注意:
这是复制/交换 idium 的示例
I can't get it to fail.
But there is not enough info to compile this line:
But the only problems I see are:
1) You have a default constructor that could create a Poruka with a NULL name:
2) Not a problem because you test for it most places but in the assignment operator you miss a test:
Notes:
Here is an example of the copy/swap idium