배열과 char*를 사용하는 C API를 지원할 때 vector는 &v[0], string은 s.c_str()을 사용
vector
vector가 비어있을 때 &v[0]은 있지 않는 메모리 주소 값을 전달하므로 미정의 동작을 방지하기 위해 empty 체크
&v[0] 대신 v.begin()로 반환하는 반복자는 실제로 포인터이지만 정확히는 포인터가 아닌 반복자이므로 사용하면 안됨
만약 사용한다면 &*v.begin()으로 사용해야 함
void doSomething(const int* pInts, size_t numInts);
if(v.empty() == false)
{
doSomething(&v[0], v.size());
}
const int*가 아닌 int*로 전달하여 요소를 변경할 수 있지만 벡터의 요소 개수를 변경하려고 하면 안됨
남은 메모리 용량으로 새 요소를 만들면 내부 데이터의 일관성이 깨지고 만약 size == capacity 상태에서 요소를 추가한다면 포인터 무효화 발생
특수한 제약을 가지고 있는 벡터를 전달한다면 API에서도 제약 사항을 만족해야 함
예를 들면 벡터의 정렬 상태를 유지해야 한다면 API에서도 정렬 상태를 유지해야 함
vector를 C API를 통해 초기화
size_t fillArray(double* pArray, size_t arraySize);
vector<double> vd(maxNumDoubles);
vd.resize(fillArray(&vd[0], fd.size()));
string
string의 데이터가 연속 메모리에 저장되지 않고, 내부 문자열 값이 널 문자로 끝나지 않을 수 있으므로 vector의 방법을 사용할 수 없음
c_str()은 문자열의 길이가 0이어도 널 문자에 대한 포인터를 반환하므로 안전
c_str()은 문자열 데이터의 사본의 포인터를 반환
void doSomething(const char* pString);
doSomething(s.c_str());
string을 C API를 통해 초기화
size_t fillString(char* pArray, size_t arraySize);
vector<char> vc(maxNumChars);
size_t charsWritten = fillString(&vc[0], fc.size());
string s(vc.begin(), vc.begin() + charsWritten);
vector나 string이 아닌 다른 STL 컨테이너의 데이터를 C API로 전달
void doSomething(const int* pInts, size_t numInts);
set<int> intSet;
vector<int> v(intSet.begin(), intSet.end());
if(v.empty() == false)
{
doSomething(&v[0], v.size());
}
'C++ > Effective STL' 카테고리의 다른 글
Effective STL 항목 19 상등 관계(equality)와 동등 관계(equivalence)의 차이를 파악하자 (0) | 2025.01.02 |
---|---|
Effective STL 항목 18 vector<bool> 보기를 돌 같이 하자 (0) | 2025.01.01 |
Effective STL 항목 15 잊지 말자! string은 여러 가지 방식으로 구현되어 있다는 사실을 (0) | 2024.12.29 |
Effective STL 항목 14 reserve는 필요 없이 메모리가 재할당되는 것을 막아 준다 (0) | 2024.12.27 |
Effective STL 항목 13 동적으로 할당한 배열보다는 vector와 string이 낫다 (0) | 2024.12.26 |