【问题标题】:Custom iterator out of bounds自定义迭代器越界
【发布时间】:2016-10-19 13:02:00
【问题描述】:

我有一个迭代器类。我们在这里称它为PIteratorMessageBuffer 被迭代并被正确输出,除非迭代器当前指向的 nSizeOfMessage plus 等于整个消息的大小(位置正确,索引 1 太大)。

如果我检查最后一个元素并减一,它应该可以工作。虽然这对我来说似乎是一种“错误的方式”。是的,我对此不太确定,所以我的问题在这段代码sn-p中显示,也许有人知道一个好的解决方案,尝试了很长时间。

是的,我确实知道如何使用调试器,我知道问题出在哪里,并且解释得很好。我不知道如何解决这个问题,除非按照我提到的方式使用。

这在 Visual Studio 2015 下编译得很好。

另请参阅主函数中的 cmets。

#include <iostream>
#include <vector>

class MessageBuffer
{
public:
    MessageBuffer(const std::string &s)
    {
        _msgBuffer.assign(s.begin(), s.end());
    }

    char &operator[](std::size_t nIndex)
    {
        return _msgBuffer[nIndex];
    }

    //more functions...

private:
    std::vector<char> _msgBuffer;
};

class PIterator
{
public:
    PIterator(MessageBuffer &b)
        : m_Ref(b)
        , m_Where(0)
    { }

    PIterator &operator=(PIterator &other)
    {
        if (this == &other)
            return *this;
        this->m_Ref = other.m_Ref;
        this->m_Where = other.m_Where;
        return *this;
    }

    //more functions...

    PIterator operator+(unsigned int nValue) const
    {
        PIterator copy(*this);
        copy.m_Where += nValue;
        return copy;
    }

    PIterator &operator+=(unsigned int nValue)
    {
        m_Where += nValue;
        return *this;
    }

    char &operator*()
    {
        return m_Ref[m_Where];
    }

private:
    MessageBuffer &m_Ref;
    std::size_t m_Where;
};

int wmain(int argv, wchar_t **args)
{
    std::string msg = "123MyMessage"; //Length 12
                                    //                    ^ Index 3, Position 4

    MessageBuffer mb(msg);

    PIterator itr(mb);

    //Calculations - here the results hardcoded
    std::size_t nSizeOfMessage = 9; //The size of the message without the numbers

                                    //itr.m_Where is 3 - That's where the non-numeric part of the message starts
    itr += 3;

    std::string needThis;

    PIterator cpy = itr + nSizeOfMessage; //itr points to the first element of the message
                                        //cpy is now out of bounds - position is correct, but index is 1 too large

    needThis.assign(&*itr, &*cpy); //boom

    return 0;
}

【问题讨论】:

  • 这种情况不就是用调试器单步调试你的代码,而不是在这里问吗?
  • @πάνταῥεῖ 我做到了,但我还是来这里寻求帮助。你想让我列出我做过和尝试过的所有事情吗?谢谢你的评论。
  • "你想让我列出我做过和尝试过的所有事情吗?" - 当然可以!
  • 最后一件事:在散文中描述问题,并在代码中标记它。它使查找变得更容易(人们不必滚动浏览您的代码即可找到主要内容,他们只需查看文本)。
  • @QPaysTaxes 好吧,您可能需要花 5 秒钟的时间滚动浏览代码,它已被标记。你能帮我解决这个问题吗?或者你能评论一下我可以改进的地方吗?

标签: c++ iterator indexoutofboundsexception


【解决方案1】:

而不是

needThis.assign(&*itr, &*cpy);

你需要使用

needThis.assign(itr, cpy);

如果您的 PIterator 满足迭代器要求,这将起作用。

调用 assign 的方式是传递指针而不是迭代器,这本身就有效。但是,要获得指针,首先要取消引用迭代器。取消引用过去的迭代器是未定义的行为,它在编译器的调试配置中被捕获。

【讨论】:

  • 我没有实现std::iterator。您可以看到 - 除了原始代码中缺少的一些函数和不同的名称 - 类 PIterator 的确切实现。因此,在我的情况下使用 char 指针是正确的。 (除非你有一个特殊的std::string 类)我的问题似乎——而且可能是——很容易解决。尽管我似乎无法为每种情况下的代码执行修复它。如有必要,我可以提供更详细的信息,问题中的代码是为了显示和解释问题。不过谢谢你的回答。
【解决方案2】:

我想出的解决方案非常简单。
我将不使用临时迭代器,而是使用 char 指针并将其地址增加消息的大小,从而始终接收正确的最后一个元素。 早该看到的。

needThis.assign(&*itr, (&*itr) + nSizeOfMessage);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 2019-03-23
    • 2015-02-04
    • 1970-01-01
    相关资源
    最近更新 更多