2013-04-15 2 views
5

포인터의 벡터를 만들려면 :어떻게 벡터에 대한 포인터를 가지고 벡터

vector<double> mv; 
mv.push_back(233); 
mv.push_back(234); 
mv.push_back(654); 
vector<double>* new_mv_pt = new vector<double> (3); 
new_mv_pt = &mv;  

cout << (*new_mv_pt)[1] << endl;  

가 어떻게 벡터에이 포인터를 저장합니다 다른 벡터를 만들 수 있습니까? 나는 이것을 시도했다 ...

vector<double*> vop = new vector<double> (3); 

vop.push_back(*new_mv_pt); 

cout << (*vop)[1] << endl; 

그러나 작동하지 않았다. 나는

+2

먼저 답을 얻으십시오. 둘째, 처음에는 메모리 사용 지점의 절반 이상을 차지하는 벡터의 메모리 관리 기능을 제거했기 때문에 이것이 끔찍한 아이디어라는 것을 알아 두십시오. –

+0

저는 왜 그가 처음에 벡터에 대한 포인터를 가지고 있는지 알아 내려고합니다. 이것은 같은 기능/클래스에있는 경우 특히 이렇게하는 것은 개념적으로 의미가 없습니다. –

답변

3

예?도 가능 시도하고, 그러나 당신은이 작업을 수행 할 필요가 무엇 :

vector<vector<double>*> vop; 

당신이 벡터 포인터의 목록을 찾고 있습니다 때문입니다.

당신은 여기에 무엇을 가지고 :

vector<double *> vop 

double 포인터의 벡터이다. 다음 주소가 new_mv_pt에서의 IT를 저장,

vector<double>* new_mv_pt = new vector<double> (3); 
new_mv_pt = &mv; 

당신은 힙에 vector<double>을 만드는, 그리고 : 당신은 메모리 여기에 누수가

vop.push_back(new_mv_pt); // <- No asterisk (you don't want to de-reference it) 
+0

메모리 누수를 방지하기 위해 두 포인터를 모두 삭제하는 방법은 무엇입니까? new_mv_pt를 삭제하려고 시도하고 런타임에 어설 션 오류가 발생합니다. 뭐가 문제 야? –

+0

두 포인터가 모두 무엇을 의미합니까? 'new_mv_pt'와 벡터에있는 것을 의미합니까? –

+0

음 new_mv_pt를 포인터 벡터없이 삭제하려고하면 런타임에 어설 션 오류가 발생합니다. 결국 나는 그것을 안전하게 삭제하는 방법을 알고 싶다. –

2

을 :

또한 당신은이 원하는 것 은 주소가 mv 인 주소을 덮어 씁니다. vector<double>은 여전히 ​​힙에 있지만 주소가 영구적으로 없어 졌으므로 delete 할 방법이 없거나 다른 방법을 사용할 수 없습니다.

이 코드 :

vector<double*> vop = new vector<double> (3); 
vop.push_back(*new_mv_pt); 
cout << (*vop)[1] << endl; 

vop 때문에 작동하지 않습니다는 double* s의 벡터이고, 당신은 그것으로 vector<double>를 삽입하려고합니다. 올바른 접근 방법은 Ben's answer을 참조하십시오.

7

와우, 천천히!

당신은 당신의 기억으로 꽤 미친 짓을하고 있습니다. 그래서 처음부터 시작합시다.

3 개의 요소가있는 단일 벡터가 있습니다. 포인터를 사용하여 벡터를 참조하려고합니다. 어떻게 보이는지 보자.

vector<double> mv; 
mv.push_back(233); 
mv.push_back(234); 
mv.push_back(654); 
// No no no no! You don't have to `new` a pointer that 
// you're going to assign to something else! 
// This is called a memory leak, and it means you've just wasted (!!!) 
// C++ memory! Don't do it 
// vector<double>* new_mv_pt = new vector<double> (3); 
// Instead, do this: 
vector<double>* ptr_to_mv = &mv; // No leak, immediately points to a vector<double> mv; 

첫 번째 비트는 처리된다. 이제 좀 더 깊숙이 들어가 봅시다. 벡터에 대한 참조 벡터를 저장하려고합니다. 좋아, 그건 공평 해. 그것에 대해 갈 수있는 몇 가지 방법이 있습니다.의는 mv의 예와 다른 것들로 돌아 가자 : 코드에서이 시점에서

vector<double> mv; 
mv.push_back(233); 
mv.push_back(234); 
mv.push_back(654); 
vector<double>* ptr_to_mv = &mv; 
// So far so good. Now, based on your question, you want 
// to have a list of these to point to. So: 
vector<vector<double>*> vop; 
vop.push_back(ptr_to_mv); // All clean. 

, 당신은 당신이 역 참조 * 또는 사용과 더불어, vector<double>*에 도착 .at() 또는 operator[]vop에 액세스 할 수 있습니다 ->는 직접 작업하기 :이 모든 당신이 mv를 참조하기 때문에

std::vector<double>* ptr_to_vector = vop[0]; // Got my pointer 
std::cout << ptr_to_vector->at(0) << std::endl; // Prints '233' 

이 (233)를 인쇄합니다. 다른 대답의 주석에서 이러한 포인터를 삭제하면 어설 션이 발생한다고 말했습니까? 두 번 삭제하면되기 때문에 발생합니다.

오래 전에 신고 한 mv을 기억하십니까? 글쎄, 당신은 역동적 인 벡터로 만들지 않았어. 너는 new이 아니고 포인터가 아니야. 따라서 함수가 종료되면 자동으로 자신을 삭제합니다. 소멸자를 호출하고 이 스택에서 죽습니다.. ptr_to_vector 또는 ptr_to_mv은 모두 mv을 참조하며, 자체적으로 정리됩니다.

당신이 그것에 삭제 호출하면 , 당신은 mv에 삭제 호출하려는 당신이 더블 삭제하는 (즉, 당신이 가리키고 기능)!

따라서 mv에 대한 포인터가 있으면 삭제하지 마십시오. 스택 기반 변수입니다. 그것은 스스로 청소할 것입니다.

여전히 다음과 같습니까? 좋아, 이제 그것으로 얻을 좀 더하자 : 이제

를, 내가 전에 말한대로 (벡터, 당신은 오래된 포인터를 우선 할당하지를 new 필요이유가있는 경우, 당신은 기억을 떠날거야). 그냥 있기 때문에 우리가 모두하지 않는 또 다른 하나는, 삭제 호출하여 정리 될 필요가 vop, 내부와 2 포인터를 가지고 :

// Our vector of double vector pointers 
vector<vector<double>*> vop; 

vector<double> mv; 
mv.push_back(233); 
mv.push_back(234); 
mv.push_back(654); 

// References a stack variable: don't delete 
vector<double>* ptr_to_mv = &mv; 
vop.push_back(ptr_to_mv); 

// Makes a fresh copy of mv. You must delete this 
// manually 
vector<double>* fresh_ptr = new vector<double>(mv); 
(*fresh_ptr)[0] = 1337; 
// changes only data in fresh_ptr, not `mv` 
vop.push_back(fresh_ptr); 

/* Blah blah blah, work */ 
// Functions about to exit, gotta clean up! 
delete fresh_ptr; 
//delete ptr_to_mv; // NO. 
//delete vop[0]; // NO! 
//delete vop[1]; // ... Already deleted from fresh_ptr 
// ... This is going to get tedious if we don't have a fresh_ptr 
// for every vector we need! 

문제를 보여줍니다 : 당신은 완전히 신선한 새로운 포인터를 만들 자동으로 청소하는 mv에 대한 참조! 벡터를 반복하고 모든 것을 삭제하면 그 불쾌한 주장이 일어납니다. 우리는 그것을 어떻게 다루고 우리가 필요로하는 깨끗한 것을 얻습니까?

지저분한 빠른 해결책 1은 단지 delete vop[1]/fresh_ptr이고 끝내야합니다. 더 나은 해결책은 리소스가 올라갈 때마다 newstd::unique_ptr이라는 훌륭한 멋진 내용으로 마무리된다는 것입니다. 코드는 다음과 같을 것입니다 :

그리고 거기에있는 모든 주석 처리 된 코드를 제거하면 갑자기 물건이 청결합니다!

물론, 지금, 내가 당신을 위해 가지고있는 마지막 질문은 다음과 같습니다 은 도대체 당신이 그 일을하는 것은 벡터의 포인터의 참조 포인터에 모든 포인터를 필요로?

+0

이것은 매우 도움이되었습니다. 넌 나를 많이 껴안아. 고맙습니다. –

+0

이것은 매우 간단한 질문에 대한 매우 상세한 답변입니다. 너는 프로 야! +1 –

관련 문제