segfault尝试访问类的字符串成员
-
28-09-2019 - |
题
我有课 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()
. 。当它这样做时,程序segfaults。我已经确定了 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
是我正在使用的诅咒库的一部分,因此此功能将每个消息打印在 Console
到诅咒屏幕的一部分。 TL
和 BR
是 Point
会员对象(两个INT),这些对象告诉屏幕上绘制的位置 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);
}
}
解决方案
我的猜测是您使用 it->getText()
, ,迭代器为空。添加检查 it != messageLog.end()
当您行走数组,然后打电话之前 it->getText()
.
其他提示
肯定是 std::vector messageLog
并不是 std::vector<Message> messageLog
?这似乎有点奇怪。
高度与向量索引有什么关系?你有:
messageLog.begin()+height-1;
为什么要将屏幕坐标添加到迭代器中?这似乎是您的问题,您很可能会过度索引,这就是为什么您要获得Sigsegv的原因。
您可能想要的是简单地迭代向量中的所有消息,并在屏幕上的特定位置显示它们。我看到您要做什么,但是如果您尝试使用迭代器来计算屏幕边界,那么您肯定会以错误的方式进行操作。尝试运行柜台或获取 messageLog.size()
然后用每次迭代重新计算高度。至于循环只是这样做:
for(it=messageLog.begin(); it!=messageLog.end(); ++it)
可能是因为 Message
在 Console
方法只是 Console
方法。因此,如果您的程序试图以另一种方法访问此对象,例如 draw
, ,您将获得此细分故障,因为执行后此对象已删除。
尝试这个(只需插入一个 new
关键词):
Console()
{
messageLog.push_back(new Message("Hello World!"));
}
在这种情况下,在控制台结束后不会删除对象。
只需记住,当您的程序不再需要它们时,删除创建的对象。