2012-01-15 2 views
8

나는이 주제에 대해 검색하고 있었고, 난이 표준에 배열 []로 변환하는 방법은 여러 가지 : 벡터, 사용 등의 발견에 배열 복사 :에성병 : 벡터

assign(a, a + n) 

또는 직접 생성자 :

std::vector<unsigned char> v (a, a + n); 

사람들은 그것이 가능 (정정) 인 경우 궁금하고 내 문제를 해결하지만해야 할 일 : 나는 궁금

myvet.resize(10); 
memcpy(&myvet[0], buffer, 10); 

이 나는 다음과 같은 코드를 가지고 있기 때문에 :

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    bufferRead.resize(totalToRead); 
    DWORD totalRead; 
    ReadFile(mhFile, &bufferRead[0], totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 

    return IDiskAccess::READ_OK; 
} 

(내가 게시물을 단순화하기 위해 ReadFile을 함수의 오류 처리를 제거한) :

IDiskAccess::ERetRead nsDisks::DiskAccess::Read(std::vector<uint8_t>& bufferRead, int32_t totalToRead) 
{ 
    uint8_t* data = new uint8_t[totalToRead]; 
    DWORD totalRead; 
    ReadFile(mhFile, data, totalToRead, &totalRead, NULL); 
    bufferRead.resize(totalRead); 
    bufferRead.assign(data, data + totalRead); 
    delete[] data; 

    return IDiskAccess::READ_OK; 
} 

을 그리고 내가하고 싶습니다.

작동하지만 안전하지 않다는 것을 사과합니다. 나는 벡터에 의해 사용 된 메모리가 연속적이기 때문에 그것이 괜찮다고 믿지만, 나는 이런 식으로 벡터를 사용하는 누군가를 본 적이 없다.

이와 같은 벡터를 사용하는 것이 맞습니까? 다른 더 좋은 옵션이 있습니까?

답변

8

std::vector으로 안전합니다. C++ 표준은 요소가 인접한 메모리 위치에 저장된다는 것을 보장합니다.

C++ 11 표준 :

23.3.6.1 클래스 templatevector 개요 [vector.overview]

벡터는 랜덤 액세스 반복기를 지원하는 일련의 용기이다. 또한, 끝에서 일정 시간의 삽입 및 삭제 작업을 지원합니다 (상각 처리). 중간에 삽입하고 지우는 것은 선형 시간이 걸립니다. 스토리지 관리는 자동으로 처리되지만 효율성을 높이기위한 힌트를 줄 수 있습니다. 벡터 요소는 연속적으로으로 저장됩니다. 즉, ifv는 avector이고 T는 bool이 아닌 다른 유형입니다. 따라서 & v [n] == & v [0] + n for all0 < = n < v .크기().

1

크기가 일 때 처음으로이됩니다. 정상적으로 작동합니다.

vector<int> v; 
v.resize(100); 
memcpy(&v[0], someArrayOfSize100, 100 * sizeof(int)); 
+3

He *는 크기를 먼저 조정합니다 (함수의 첫 번째 줄 참조). – celtschk

+1

나는 그가 그렇게하지 못한 것을 암시하지는 않았다. 나는 그 중요성을 강조하고있었습니다. – TheBuzzSaw

+1

* 의미가 *있을 수는 없지만 그렇게했을 수도 있습니다. – celtschk

2

vector의 메모리가 연속 할당을 보장하고, 서명 숯불는 POD이다, 따라서 그것은 (당신은 물론, 할당 된 것보다 더 많은 복사하지 않는 가정) 그것에 memcpy에 완전히 안전합니다.

1

예, memcpy을 사용하는 솔루션은 정확합니다. vector에 의해 보유 된 버퍼는 연속적이다. 하지만 형식이 안전하지 않으므로 assign 또는 std::copy을 선호합니다.

5

네, 그렇게하는 것이 좋습니다. 더 잘 보이는 경우 &myvet[0] 대신 myvet.data()을 사용하고 싶지만 둘 다 똑같은 효과가 있습니다.또한, 상황이 허락한다면 std::copy을 대신 사용할 수 있으며 더 많은 유형 안전성과 기타 모든 C++ 표준 라이브러리 기능을 사용할 수 있습니다.

vector이 사용하는 저장소는 연속적으로 보장되어 버퍼 또는 다른 기능으로 사용하기에 적합합니다.

vector 그 작업 중 하나에 버퍼 크기를 조정하고 무효화 할 수 있기 때문에 당신이 data 또는 &v[0]에서 얻을 포인터를 사용하는 동안 당신은 (거기에 push_back 등을 호출 등)을 vector을 수정하지 않는 것이 확인 포인터

3

이 접근법은 정확합니다. 이는 표준에서 요구하는 인접 메모리가있는 벡터에만 의존합니다. 나는 C++ 11에서 버퍼에 대한 포인터를 반환하는 벡터에 새로운 data() 멤버 함수가 있다고 생각한다. 또한 memcpy의 경우 배열의 크기가 아닌 바이트 단위로 크기를 전달해야합니다.