배열과 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());
}

+ Recent posts

목차