尝试访问类的字符串成员时出现段错误

时间:2010-06-21 21:16:58

标签: c++ segmentation-fault stdstring

我有一个Messagestd::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()的迭代器。当它发生时,该程序会出现段错误。我已确定textMessage构造函数中有效。但是,我无法判断它是否在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屏幕的一部分。 TLBRPoint个成员对象(两个整数),用于指示在屏幕上绘制Console的位置。我在原始问题中省略了MessageConsole的部分内容,希望能让事情变得更清晰,但如果你需要我发布整个课程,那么我就可以。它们不会太长。

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);
            }
        }

4 个答案:

答案 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!"));
    }

在这种情况下,控制台结束后不会删除该对象。

请记住删除程序不再需要时创建的对象。