2009-10-20 5 views
5

최근에 나는 std::string s 주어진 다음 진술이 사실이 아니라고 나타났습니다.왜 std :: string :: max_size() == std :: string :: allocator :: max_size()

s.max_size() == s.get_allocator().max_size(); 

나는이 흥미로운 기본적 std::string으로 size_type(-1)의 이론적 인 한계가 std::allocator<char> 사용 찾을 (예 내가 2의 보수를 있으리라 믿고있어 알을하지만 실제 질문에 관련되지 않은). 실용적인 제한은 이보다 훨씬 적을 것입니다. 일반적인 32 비트, x86 시스템에서 커널은 2GB (아마도 1GB)의 주소 공간을 차지하며 실용적인 상한선은 훨씬 작습니다.

어쨌든 GNU libstdC++의 std::basic_string<>::max_size()은 사용하는 할당자가 무엇을 말하는지와 상관없이 같은 값을 반환하는 것처럼 보입니다 (1073741820과 같은 것).

그럼 질문이 남아 있습니다. 왜 std::basic_string<>::max_size()은 단지 get_allocator().max_size()을 반환하지 않습니까? 이것이 나에게 가상의 상한선 인 것 같습니다. 할당이 짧아지면 std::bad_alloc을 던집니다. 왜 시도하지 않으시겠습니까?

이것은 다른 무엇보다 호기심입니다. 나는이 두 구현이 적어도이 구현에서 왜 분리되어 있는지 궁금합니다.

+0

"그리고 경우를. 할당이 짧아지면, 그냥 std :: bad_alloc을 던질 것이므로, 왜 시도하지 않겠습니까? "나는 당신에게 대답 할 수있다. 사람들은 커다란 문자열을 처리해야하고 커다란 문자열 덩어리로 나눌 필요가있을 수 있습니다. 실제로 max_size가보고하는 내용에 의존 할 수없는 경우 임시 제한에 의존해야합니다. – GManNickG

+0

나는 당신의 요지를 보았지만, 나는 동의하지 않는다. 현실은 꽤 많은 문자열 크기 (= max_size()가 외부 변수에 의존하기 때문에 실패 할 가능성이 있다고 가정해야한다는 것입니다 (힙에서 사용할 수있는 양). –

+0

동의. 나의 유일한 요점은 그들이 최소한 정확성을 기하기 위해 노력해야한다는 것입니다. 실용적인 숫자에 최선의 희망을주십시오. :) 힘든 질문. – GManNickG

답변

10

에서 Microsoft Connect는 질문과 관련된 버그를 게시했습니다. Microsoft는 그것에 대한 흥미로운 대답을 가지고 있습니다 :

우리는 Max_size()가 의도 한 목적이 무엇인지 명확히 설명하지 않은 표준에 대한 우리의 해석에 따라이를 디자인으로 해결했습니다. Allocator max_size()는 "X :: allocate()"(C++ 03 20.1.5 [lib.allocator.requirements]/표 32)로 의미있게 전달 될 수있는 가장 큰 값으로 설명되지만 container max_size "가능한 가장 큰 컨테이너의 크기 (size) (23.1 [lib.container.requirements]/표 65)"로 설명됩니다. 컨테이너 max_size()가 할당 자 max_size()에서 파생되어야하는지 여부 또는 방법을 설명하지 않습니다. 우리는 수년간 컨테이너 max_size()를 할당 자 max_size()에서 직접 파생시킨 다음 오버플로 검사 등에이 값을 사용했습니다. 표준과 같은 다른 해석이 가능하지만 명확하지 않습니다. 스탠다드의 표현은 분명히 여기에 설명되어있다. 그런 일이 발생하지 않는 한, 우리는 현재 구현을 변경하지 않고 두 가지 이유로 남겨두기로 결정했습니다. (1) 다른 고객이 우리의 현재 행동에 의존하고 있으며, (2) max_size()가 근본적으로 아무것도 사지 않습니다. 할당 자 (컨테이너와 같은)를 소비하는 것들은 allocate()가 실패 할 때를 예측하기 위해 allocator max_size()를 사용할 수 있습니다. 그러나 할당 자 (allocator)가 메모리를 제공할지 결정하기 때문에 단순히 allocate()를 호출하는 것이 더 좋은 테스트입니다. 컨테이너를 소비하는 것은 size()가 얼마나 큰지를 보증하기 위해 container max_size()를 사용할 수 있지만 size_type의 범위는 더 간단합니다.

here 코어 이슈 # 197을 찾을 수 있습니다. 위원회는 스탠다드의 문구를 개선 할 것을 요청했지만, 거부되었다.

질문에 대한 대답은 "왜 ..?"표준이 max_size()의 의도 된 목적을 명확하게 설명하지 못한다는 것입니다.

4

나는 완전히 알고 있지만 지금까지 알고있는 한 std::basic_string은 현재 표준에서 문자열을 연속 메모리에 저장하는 데 제한되지 않습니다. 예를 들어, 여러 청크로 저장할 수 있습니다. 그런 각각의 덩어리는 std::allocator::max_size()으로 제한되지만 합계는 그보다 클 수 있습니다.

또한 STL 컨테이너의 경우 인 것 같습니다. 그리고 결국 std::basic_string은 컨테이너입니다.

+0

아무도 이런 식으로 구현하지 않는다는 것을 제외하고는 다음 표준이 그것을 허용하지 않을 수도 있지만 (완전히 확신 할 수는 없다) OP는 할당자가 허용하는 것보다 현저히 작음을보고있다. – UncleBens

1

GCC의 구현은 어떻게 계산합니까? max_size (단일 블록으로 할당 된 내부 하우스 키핑 객체의 크기를 빼야합니다.) 그 다음에는 max_size()이 4 분의 1을 반환한다고 덧붙이겠습니다. 이론적 근거가 없으므로 아마 안전 마진일까요? (로프 클래스도 제공해야합니다. VC++ max_size() 반환 한 적은 allocator.max_size() 이상으로)

는 - 아마 null 문자를 종료 설명하기 위해

관련 문제