2013-07-12 2 views
2

그래서 최근에 boost 및 C++ 11 스마트 포인터에 익숙해졌습니다. 따라서 메모리 관리가 훨씬 쉬워집니다. 그리고 무엇보다도, 그들은 대개 여전히 레거시 코드 (get 호출을 사용하여)로 작업 할 수 있습니다.스마트 포인터를 사용하여 동적으로 지그재그 배열 할당

그러나 계속 실행중인 큰 구멍은 다차원 지그재그 배열입니다. 이를 수행하는 올바른 방법은 boost::scoped_array<boost::scoped_array<double>> 또는 vector<vector<double>>입니다. 그러면 청소가 잘됩니다. 그러나이 중 double**을 쉽게 기존 코드로 보낼 수는 없습니다.

이렇게하는 방법이 있습니까, 아니면 스마트가 아닌 지그재그 배열로 고정되어 있습니까?

+0

"기존 코드"의 API는 무엇입니까? 가변형 배열을'double **'으로 어떻게 넘길 수 있는지 보지 못합니다 - 크기 정보는 어디에 있습니까? – Casey

답변

0

내가 저장 std::vector<std::vector<double>>으로 시작 했죠 구조가 매우 정적 인 경우는 예외입니다.

배열 배열을 생성하려면 transform_to_vector(storage, [](std::vector<double>& v) { return v.data(); })과 같은 구문을 사용하여 위의 저장소를 변환하여 std::vector<double*> (transform_to_vector)을 생성해야합니다.

두 개를 동기화하면 작은 클래스로 묶을 수 있습니다. 들쭉날쭉 한 배열이 상대적으로 크기가 고정되어있는 경우

, 내 버퍼를 만들 std::vector<std::size_t>를 취할 것 (또는 어쩌면 std::initializer_list<std::size_t> - 실제로하는 template<typename Container>을, 나는 두 번 단지 for(:) 위에을 좋겠하고, 발신자를 보자 어떤 컨테이너를 제공했는지 선택), 크기의 합계가있는 std::vector<double>을 하나 작성한 다음 지시 된 오프셋에서 std::vector<double*>을 빌드하십시오.

크기를 조정하면 비용이 많이 드는 데 이는 단점입니다.

std::vector을 사용하면 멋진 API는 beginend 값에 액세스 할 수 있습니다. 하나의 큰 버퍼가있는 경우 하위 배열의 범위보기를 새 코드 (double* begin()double* end()을 포함하는 구조로 표시하고 여기에있는 동안은 double& operator[]std::size_t size() const { return end()-begin(); } 임)로 인해 영광을 누릴 수 있습니다. 레거시 인터페이스에 대한 C 호환성을 유지하면서 C++ 컨테이너 스타일의 뷰를 완벽하게 지원합니다.

0

C++ 11에서 작업하는 경우 scoped_array<T>이 아닌 unique_ptr<T[]>으로 작업해야합니다. 그것은 scoped_array이 할 수있는 모든 것을 할 수 있습니다.

직사각형 배열이 필요한 경우 기본 데이터를 보유하려면 unique_ptr<double[]>을 사용하고 행 기준을 보유하려면 unique_ptr<double*[]>을 사용하는 것이 좋습니다. 이 같은 뭔가를 작동합니다 :

unique_ptr<double[]> data{ new double[5*3] }; 
unique_ptr<double*[]> rows{ new double*[3] }; 
rows[0] = data.get(); 
for (size_t i = 1; i!=5; ++i) 
    rows[i] = rows[i-1]+3; 

는 그런 다음 double**을 복용 함수에 rows.get()를 전달할 수 있습니다. 이 접근법은 비 직사각형 배열에서도 작동 할 수 있습니다. 배열 작성시 배열의 형상이 알려지면 모든 데이터를 한 번에 할당하고 rows을 적절한 오프셋으로 지정할 수 있습니다. (단순한 루프처럼 단순하지는 않습니다.)

이렇게하면 두 개의 할당 만 수행하기 때문에 참조 및 메모리 사용의 지역성이 향상됩니다. 모든 데이터는 메모리에 함께 저장되며 별도의 할당에 대한 추가 오버 헤드는 없습니다.

지그재그 배열을 만든 후에 지오메트리 배열을 변경하려면이 솔루션을 적용 할 수 있도록 저장소를 관리하는 원칙적인 방법을 찾아야합니다. 그러나 scoped_array을 사용하여 형상을 변경하면 (swap()의 특정 용도가 필요함) 어색하며, 이것이 문제가되지 않는다면 놀랄 일이 아닙니다.

(이 방법은 scoped_array뿐만 아니라 unique_ptr<[]> 작업 할 수 있습니다, 우리가 지금 C++ (11)에있을 때부터 단순히 unique_ptr를 사용하여 설명하고있다.)

관련 문제