10. std::string 의 작은 문자열 최적화(SSO)

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C++
// 주제: std::string 의 작은 문자열 최적화(Small String Optimization, SSO)
//
// 과제: 아래 프로그램의 출력을 예측하고, 다음을 내부 동작으로 설명하라.
//   1) 짧은 문자열과 긴 문자열 중 어느 쪽이 힙 할당을 하고 어느 쪽이 안 하는가?
//      그 경계는 무엇으로 정해지는가?
//   2) inObject() 가 짧은/긴 문자열에서 각각 무엇을 출력하며 그 의미는?
//   3) 긴 문자열을 move 한 뒤, 원본(s2)과 대상(s3)의 데이터 버퍼 주소 관계는?
//      짧은 문자열의 move 는 긴 문자열의 move 와 무엇이 다른가?
//   (capacity 의 구체적 수치는 표준 라이브러리 구현에 따라 다를 수 있다.
//    libstdc++ 기준으로 설명하라.)

#include <cstdint>
#include <iostream>
#include <string>
#include <utility>

// 문자 버퍼가 문자열 객체 자신의 메모리 안에 있는지(=SSO 활성) 검사
static bool inObject(const std::string& s) {
    auto base = reinterpret_cast<uintptr_t>(&s);
    auto data = reinterpret_cast<uintptr_t>(s.data());
    return data >= base && data < base + sizeof(std::string);
}

int main() {
    std::cout << "sizeof(std::string) = " << sizeof(std::string) << "\n";

    std::string s1 = "hello";              // 짧은 문자열
    std::cout << "s1 cap=" << s1.capacity()
              << " inObject=" << inObject(s1) << "\n";

    std::string s2(100, 'x');              // 긴 문자열
    std::cout << "s2 cap=" << s2.capacity()
              << " inObject=" << inObject(s2) << "\n";

    const char* before = s2.data();
    std::string s3 = std::move(s2);        // 긴 문자열 이동
    std::cout << "s3.data()==old s2.data()? " << (s3.data() == before) << "\n";
    std::cout << "s2 empty after move? " << s2.empty() << "\n";

    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.