ошибка выполнения при использовании карты std для сравнения - PullRequest
0 голосов
/ 07 декабря 2018

Во-первых, здесь задается несколько похожий вопрос: Необычная ошибка выполнения std :: map .

, но поскольку здесь нет реального решения, я бы хотел задать его еще раз,потому что я действительно застрял и ничего не понимаю.

Мой код выглядит следующим образом:

struct MyObj{
//constructor
MyObj(){}
std::map<std::string, std::string> m_fooMap;

bool operator==(const MyObj& other)
{
    if (m_fooMap.size() != other.m_fooMap.size())
        return false;

    std::map<std::string, std::string>::const_iterator i, j;
    i = m_fooMap.cbegin();
    j = other.m_fooMap.cbegin();
    for (; i != m_fooMap.cend(), j != other.m_fooMap.cend(); ++i, ++j)
    {
        if(i->first.empty() || j->first.empty())
            continue;

        if (i->first != j->first)
            return false;

        if (i->second != j->second)
            return false;
    }

  return true;
}

bool operator!=(const MyObj& other)
{
    return !operator==(other);
}
};

struct AnotherObj{
std::map<std::string, MyObj> m_collectionOfObjs; //always guaranteed to contain atleast one entry

bool operator==(const AnotherObj &other) const
    {
        for (auto& objIt : m_collectionOfObjs)
        {
            auto findSeriesIt = other.m_collectionOfObjs.find(objIt.first);

            if (findSeriesIt == other.m_collectionOfObjs.end())
                return false;

            //else found, see if the internal content is the same?
            else
            {
                if (objIt.second != findSeriesIt->second)
                    return false;
            }
        }

        //else
        return true;
    }
};

Теперь у меня есть std :: vector anotherObjVec;И мне нужно сравнить элементы внутри этого вектора, друг с другом.для которого я использую оператор ==.

Теперь в случайных случаях каждый раз, даже если входные данные одинаковы, кажется, что во время выполнения возникает ошибка.Ошибка указывает внутри файла «xtree» на следующий код:

_Nodeptr _Lbound(const key_type& _Keyval) const
    {   // find leftmost node not less than _Keyval
    _Nodeptr _Pnode = _Root(); //<------------ THIS line is where it points to
    _Nodeptr _Wherenode = this->_Myhead;    // end() if search fails

    while (!this->_Isnil(_Pnode))
        if (_DEBUG_LT_PRED(this->_Getcomp(), this->_Key(_Pnode), _Keyval))
            _Pnode = this->_Right(_Pnode);  // descend right subtree
        else
            {   // _Pnode not less than _Keyval, remember it
            _Wherenode = _Pnode;
            _Pnode = this->_Left(_Pnode);   // descend left subtree
            }

    return (_Wherenode);    // return best remembered candidate
    }

Я застрял и понятия не имею, что делать дальше.Я даже пытался запустить конструктор так:

MyObj() : m_fooMap(std::map<std::string, std::string>()){}

Использование C ++ 11, Visual Studio 2012 (v110)

Ответы [ 4 ]

0 голосов
/ 12 декабря 2018

Оказывается, карта не была создана правильно.Это случилось со мной, потому что я использовал std :: shared_ptr и сохранял его в std :: vector.Затем, повторяя его, один из общих ptrs был nullptr.Понятия не имею, почему это произошло, потому что это общий ptr, и он находится в векторе, он должен продолжать подсчет ссылок, но я просто изменил технику итерации по вектору, и теперь она работает.

0 голосов
/ 07 декабря 2018

Вы сравниваете итераторы с разных карт:

auto findSeriesIt = other.m_collectionOfObjs.find(objIt.first);
if (findSeriesIt == m_collectionOfObjs.end())
    return false;

findSeriesIt с карты other.m_collectionOfObjs, но вы сравниваете ее с окончанием m_collectionOfObjs.Должно быть:

auto findSeriesIt = other.m_collectionOfObjs.find(objIt.first);
if (findSeriesIt == other.m_collectionOfObjs.end())
    return false;
0 голосов
/ 07 декабря 2018

Ваши слова

, хотя входные данные совпадают, похоже, что во время выполнения произошла ошибка.

, поэтому operator== должно вернуть trueв конце блока, но ваша функция не возвращает никакого значения (если ваши карты пусты, ваши функции достигают конца блока, где нет оператора возврата):

bool operator==(const MyObj& other)
{
    if (m_fooMap.size() != other.m_fooMap.size())
        return false;

    std::map<std::string, std::string>::const_iterator i, j;
    i = m_fooMap.cbegin();
    j = other.m_fooMap.cbegin();
    for (; i != m_fooMap.cend(), j != other.m_fooMap.cend(); ++i, ++j)
    {
        if(i->first.empty() || j->first.empty())
            continue;

        if (i->first != j->first)
            return false;

        if (i->second != j->second)
            return false;
    }
  // ??? return is missing here
}

, поэтому неопределенное поведение

( из ):

Выход из конца функции, возвращающей значение (кроме main) без оператора return,неопределенное поведение.

0 голосов
/ 07 декабря 2018

i != m_fooMap.cend(), j != other.m_fooMap.cend() использует оператор запятой, отбрасывая первый операнд.Он не проверяет оба условия, поэтому, когда i равен конечному итератору, он может быть позднее разыменован.Вместо этого вы должны использовать оператор and:

(m_fooMap.cend() != i) and (other.m_fooMap.cend() != j);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...