Что вызывает повышение :: ниже, чтобы провалилось утверждение is_singular? - PullRequest
3 голосов
/ 22 декабря 2010

Иногда я получаю странное поведение от boost :: lower, когда вызывается на std :: wstring.В частности, я видел следующее утверждение сбоя в сборке выпуска (но не в сборке отладки):

Assertion failed: !is_singular(), file C:\boost_1_40_0\boost/range/iterator_range.hpp, line 281 

Я также видел ошибки памяти после вызоваboost :: to_lower в таких контекстах, как:

void test(const wchar_t* word) {
    std::wstring buf(word);
    boost::to_lower(buf);
    ...
}

Замена вызовов boost::tolower(wstr) на std::transform(wstr.begin(), wstr.end(), wstr.begin(), towlower), кажется, решает проблему;но я хотел бы знать, что происходит не так.

Мое предположение заключается в том, что, возможно, проблема связана с изменением регистра символов Юникода - возможно, размер кодировки символа в нижнем регистре отличается отразмер кодировки исходного символа?

У кого-нибудь есть идеи, что здесь происходит?Могло бы помочь, если бы я знал, что означает «is_singular ()» в контексте повышения, но после нескольких поисков в Google я не смог найти для него никакой документации.

Соответствующие версии программного обеспечения: Повышение 1.40.0;MS Visual Studio 2008.

Ответы [ 2 ]

3 голосов
/ 22 декабря 2010

После дальнейшей отладки я выяснил, что происходит.

Причиной моей проблемы было то, что один проект в решении не определял NDEBUG (несмотря на то, что находился в режиме выпуска), в то время как все остальные модулимы.Boost выделяет некоторые дополнительные поля в своих структурах данных, которые он использует для хранения отладочной информации (например, была ли инициализирована структура данных).Если у модуля A отключена отладка, он создаст структуры данных, которые не содержат этих полей.Затем, когда модуль B, у которого включена отладка, получит эту структуру данных, он попытается проверить те поля (которые не были выделены), что приведет к случайным ошибкам памяти.

Определение NDEBUG во всех проектах в решении решило проблему.

3 голосов
/ 22 декабря 2010

Диапазон итераторов должен быть единственным, если он создан с помощью конструктора по умолчанию (хранит единичные итераторы, то есть не представляет диапазон).Поскольку трудно поверить, что функция boost to_lower может создать отдельный диапазон, предполагается, что проблема может быть и в другом месте (в результате некоторого неопределенного поведения, такого как использование неинициализированных переменных, которые могут быть инициализированы до некоторого известного значенияв сборках отладки).

Подробнее о Heisenbugs .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...