2010-12-21 2 views
3

때때로 std :: wstring에서 호출 될 때 boost :: lower에서 이상한 동작이 발생합니다. 특히, 나는 다음과 같은 주장은 릴리스 빌드에서 실패 보았다 (그러나 디버그 빌드에서 하지) :boost :: lower가 is_singular 어설 션을 실패하게하는 원인은 무엇입니까?

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

나는 또한 상황에서 부스트 :: to_lower를 호출 한 후 메모리 오류를 것으로 보인다 무엇을 보았다 같은 :

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

std::transform(wstr.begin(), wstr.end(), wstr.begin(), towlower)boost::tolower(wstr)이 문제를 해결하기 위해 표시되는 전화 교체; 하지만 무슨 일이 일어나고 있는지 알고 싶습니다.

아마도 가장 문제는 유니 코드 문자의 대소 문자를 변경하는 것과 관련이있는 것 같습니다. 대문자 문자의 인코딩 크기가 원본 문자의 인코딩 크기와 다를 수 있습니다.

여기에 어떤 일이 벌어 질지 상상해보십시오. 내가 "boost_extular()"가 boost의 문맥에서 의미하는 것을 알았다면 도움이 될지 모르지만, 몇 번의 Google 검색을 수행 한 후에는 문서를 찾을 수 없었습니다.

관련 소프트웨어 버전 : 부스트 1.40.0; Microsoft Visual Studio 2008.

답변

3

추가 디버깅 후, 나는 무슨 일이 일어나고 있는지 알아 냈습니다.

내 문제의 원인은 솔루션의 한 프로젝트가 (릴리스 모드 임에도 불구하고) NDEBUG를 정의하지 않고 다른 모듈이 모두 있다는 것입니다. Boost는 데이터 구조에 디버그 정보 (예 : 데이터 구조가 초기화되었는지 여부)를 저장하는 데 사용되는 몇 가지 추가 필드를 할당합니다. 모듈 A가 디버깅을 해제 한 경우 해당 필드가없는 데이터 구조가 생성됩니다. 그런 다음 디버깅이 켜져있는 모듈 B가 해당 데이터 구조를 사용하면 할당되지 않은 필드를 확인하여 임의의 메모리 오류가 발생하는지 확인합니다.

NDEBUG를 에 정의하면 솔루션의 모든 프로젝트에서 문제가 해결됩니다.

3

iterator 범위는 기본 생성자 (단일 반복자를 저장합니다. 즉 범위를 나타내지 않음)로 생성 된 경우에만 단항 형이어야합니다. 부스트의 to_lower 함수가 단수 범위를 생성하는 것을 관리하는 것이 다소 어렵 기 때문에 문제는 다른 곳에서도 발생할 수 있음을 알 수 있습니다 (디버그에서 알려진 값으로 초기화 될 수있는 초기화되지 않은 변수 사용과 같은 일부 정의되지 않은 동작의 결과) 빌드).

Heisenbugs에 대한 자세한 내용을 읽으십시오.

관련 문제