2016-11-23 1 views
2

우선, 내 동기는 컴퓨터 커널과 같은 C의 효율적인 메모리 관리를 수행하는 것입니다. 그리고 나는 std::unique_ptrstd::vector을 사용하려고, 내 코드는 여기에 연습 p_data 각 할당 된 배열을 인덱싱에 다른 컨테이너 (예 :지도)에 저장 될 수있는 unique_ptr과 적절한 컨테이너를 사용하여 메모리 관리

// my data container 
typedef std::unique_ptr<double> my_type; 
std::vector<my_type> my_storage; 

// when I need some memory for computation kernel 
my_storage.push_back(my_type()); 
my_storage.back.reset(new double[some_length]); 

// get pointer to do computational stuff 
double *p_data=my_storage.back.get(); 

아래 공지 사항 같은 도메인 문제에 따라 보이는 그럼에도 불구하고, 내 주요 질문은 여기에

  1. 입니다 std::vector 좋은 선택인가? std::list/set과 같은 다른 컨테이너는 어떻습니까?

  2. 할당 방법에 근본적인 문제가 있습니까? 내가 어떤 작업에 p_data를 사용 후

  3. 는 지금이 가장 좋은 방법은 여기에 무엇인가, 원시 포인터 p_data가 가리키는 메모리 청크를 해제하려면, 가정?

+1

, 대신'표준 : shared_ptr'을 사용할 수 있습니다, 그리고 당신은 모든 원시 포인터를 사용하지 않는 : 대신 사용해보십시오. – Mine

+0

'std :: unique_ptr ','new double []'을 사용하고,'std :: make_unique'를 선호한다면이 불일치를 피할 수 있습니다. – Jarod42

+0

@Mine : 이것은 명확하지 않은 문제의 OP 사양에 따라 완전히 자원 낭비 일 수 있습니다. – Jack

답변

1

우선 당신이 전문화 std::unque_ptr<T[]>를 사용할 필요가 배열을 할당하거나 사용자가 메모리 출시하지만, 간단한 deletedelete []을받지 않습니다 경우.

std::vector은 다른 것을 사용해야하는 명백한 이유가없는 한 좋은 선택입니다. 예를 들어 당신이 용기 내부의 많은 요소를 이동하려는 경우 다음 std::list 주위에 물건을 이동하는 것이 더 (덜 memmove 작업을 수행 할 수 있습니다.

을가 utlization의 패턴에 주로 의존 메모리를 관리하는 방법에 대해서. my_storage는 경우 모든 것을 책임지고있는 메인 (unique_ptr은 소유권을 표현하기 때문에 사용자의 지정에 따라) 메모리를 해제 할 수있는 유일한 사람이됩니다. my_storage[i].reset()을 호출하여 간단히 수행 할 수 있습니다.

관리 대상의 원시 포인터 다른 컬렉션 내부의 객체는 메모리가 해제되면 포인터가 매달 리도록 유도합니다 (예 :

).
using my_type = std::unique_ptr<double[]>; 
using my_storage = std::vector<my_type>; 

my_storage data; 
data.push_back(my_type(new double[100])); 

std::vector<double*> rawData; 
rawData.push_back(data[0].get()); 

data.clear(); // delete [] is called on array and memory is released 
*rawData[0] = 1.2; // accessing a dangling pointer -> bad 

data이 마지막으로 다음 문제가 없는지 해제 경우 메모리가 여전히 유효한 경우, 그렇지 않으면 당신은 적어도 당신은 확인할 수있을 것 그래서 std::unique_ptr에 const를 참조를 저장할 수, 문제 여부를 수 예 :

using my_type = std::unique_ptr<double[]>; 
using my_managed_type = std::reference_wrapper<const my_type>; 
std::vector<my_managed_type> rawData; 
+0

이 경우 벡터는 shared_ptr를 저장하므로 포인터 (메모리)를 바꿔도 std :: list는별로 도움이되지 않을까요? – lorniper

0

, 어떤 STL 컨테이너와 std::unique_ptr를 사용 std::vector을 포함, 일반적으로 괜찮습니다. 그러나 std::unique_ptr 올바른 방법을 사용하고 있지 않습니다. 어레이의 특수 버전을 사용하고 있지 않으므로 back.reset()을 사용하지 않아도됩니다.

당신은`p_data`가 다른 용기 사이에 공유 될 것으로 예상되는 경우
// my data container 
typedef std::unique_ptr<double[]> my_type; 
// or: using my_type = std::unique_ptr<double[]>; 

std::vector<my_type> my_storage; 

my_type ptr(new double[some_length]); 
my_storage.push_back(std::move(ptr)); 
// or: my_storage.push_back(my_type(new double[some_length])); 
// or: my_storage.emplace_back(new double[some_length]);