我有一个Message
类std::string
作为数据成员,定义如下:
class Message
{
// Member Variables
private:
std::string text;
(...)
// Member Functions
public:
Message(const std::string& t)
: text(t) {}
std::string getText() const {return text;}
(...)
};
此类用于另一个类的向量中,如下所示:
class Console
{
// Member Variables
private:
std::vector<Message> messageLog;
(...)
// Member Functions
public:
Console()
{
messageLog.push_back(Message("Hello World!"));
}
void draw() const;
};
在draw()
中,有一个调用getText()
的迭代器。当它发生时,该程序会出现段错误。我已确定text
在Message
构造函数中有效。但是,我无法判断它是否在Console
内有效。我假设它是,但如果我尝试检查Console
的messageLog的索引,gdb告诉我这个:
(gdb) p messageLog[0]
One of the arguments you tried to pass to operator[] could not be converted to what
the function wants.
任何人都知道发生了什么事?
编辑:这是draw()
。 TCODConsole
是我正在使用的curses库的一部分,因此该函数将Console
中的每条消息打印到curses屏幕的一部分。 TL
和BR
是Point
个成员对象(两个整数),用于指示在屏幕上绘制Console
的位置。我在原始问题中省略了Message
和Console
的部分内容,希望能让事情变得更清晰,但如果你需要我发布整个课程,那么我就可以。它们不会太长。
void Console::draw() const
{
int x = TL.getX(), y = TL.getY();
int width = BR.getX() - TL.getX();
int height = BR.getY() - TL.getY();
// draw the Console frame
TCODConsole::root->printFrame(x, y, width, height, true);
// print the Console's messages
vector<Message>::const_iterator it;
for(it=messageLog.begin(); it<messageLog.begin()+height-1; ++it)
{
string message = "%c" + it->getText();
TCODConsole::setColorControl(TCOD_COLCTRL_1,
it->getForeColor(),
it->getBackColor());
y += TCODConsole::root->printRectEx(x, y, width, height,
TCOD_BKGND_NONE,
TCOD_LEFT,
message.c_str(),
TCOD_COLCTRL_1);
}
}
答案 0 :(得分:2)
我的猜测是,使用it->getText()
时,迭代器为NULL。在走数组时,在调用it != messageLog.end()
之前添加一个检查it->getText()
。
答案 1 :(得分:0)
绝对是std::vector messageLog
而不是std::vector<Message> messageLog
吗?这看起来有点奇怪。
答案 2 :(得分:0)
高度与矢量索引有什么关系?你有:
messageLog.begin()+height-1;
为什么要将屏幕坐标添加到迭代器?这似乎是你的问题而且你最有可能过度索引,这就是你获得SIGSEGV的原因。
您可能想要的是简单地迭代向量中的所有消息并将其显示在屏幕上的特定位置。我看到你正在尝试做什么,但是如果你试图用迭代器来计算屏幕边界,你肯定是错误的方式。尝试运行计数器或获取messageLog.size()
,然后在每次迭代时重新计算高度。至于循环,只需:
for(it=messageLog.begin(); it!=messageLog.end(); ++it)
答案 3 :(得分:-2)
这可能是因为Message
方法中创建的Console
对象的范围只是Console
方法。因此,如果您的程序试图以另一种方法(例如draw
)访问此对象,则会出现此分段错误,因为此对象在执行后会被删除。
尝试此操作(只需插入new
关键字):
Console()
{
messageLog.push_back(new Message("Hello World!"));
}
在这种情况下,控制台结束后不会删除该对象。
请记住删除程序不再需要时创建的对象。