2012-11-12 2 views
0

개체의 벡터와 그 개체에 대한 다른 포인터 벡터를 만들고 싶다고합니다 (동적 메모리를 사용할 수 없음). 내가하는 일은 다음 예제에 나와 있습니다. 정적으로 할당 된 객체에 대한 포인터를 벡터에 저장하는 방법은 무엇입니까?

#include <iostream> 
#include <vector> 

using namespace std; 

class Foo { 
public: 
    int bar; 
    Foo(int x) : bar(x) { 
    } 
}; 

int main() { 
    vector<Foo> foos; 
    vector<Foo*> pFoos; 
    for (int i = 0; i < 10; i++) { 
    Foo foo(i); 
    foos.push_back(foo); 
    pFoos.push_back(&foos.back()); 
    } 

    for (int i = 0; i < 10; i++) { 
    cout << foos[i].bar << endl; 
    cout << pFoos[i]->bar << endl; 
    } 
} 

나는이 일을해야한다고 생각하기 때문에 foos 저장 나는 (원래 foo가 정의되기 때문에, 그래서 그에 대한 참조를 저장 안) 사본에 대한 참조를 저장 한 다음 오브젝트의 복사 및 . 그러나 이것이 내가 얻은 것입니다.

0 
36741184 
1 
0 
2 
2 
3 
3 
4 
4 
5 
5 
6 
6 
7 
7 
8 
8 
9 
9 

첫 번째 숫자는 pFoos입니다. 또한 매번 큰 숫자가 바뀝니다. 이 정의되지 않은 동작을 일으키는 어떤 것도 표시되지 않습니다. 누군가 내가 뭘 잘못하고 있다고 말할 수 있습니까?

+0

하지만'foo'는 정적이 아니고 로컬 저장소입니다 ... – rodrigo

+0

@rodrigo 벡터가 그 복사본을 만들 것이라고 생각 했습니까? – gsingh2011

+0

그리고 그 코멘트에 대한 내 참조는 다음과 같습니다 : http://www.cplusplus.com/reference/stl/vector/push_back/ – gsingh2011

답변

8

벡터에 항목을 추가하면 이전 반복기가 모두 무효화됩니다. 벡터에서 push_back을 호출하면 벡터가 내부 저장소를 재 할당해야하는 경우 이전에 가져온 포인터가 유효하지 않게 될 수 있습니다.

for (int i = 0; i < 10; i++) { 
    foos.push_back(Foo(i)); 
} 

for (int i = 0; i < 10; i++) { 
    pFoos.push_back(&foos[i]); 
} 

또는 로드리고 댓글을 달았습니다 :

foos.reserve(10) 

for (int i = 0; i < 10; i++) { 
    Foo foo(i); 
    foos.push_back(foo); 
    pFoos.push_back(&foos.back()); 
} 

for (int i = 0; i < 10; i++) { 
    cout << foos[i].bar << endl; 
    cout << pFoos[i]->bar << endl; 
} 
+2

모든 푸시 백이 재 할당을 유발하지는 않습니다. 할당 된 공간이 모두 소모 된 경우에만. – jrok

+1

바꾸기 "할 수 있습니다"로 대체하고 해결합니다. 'foos.reserve (10) '를 호출하면 UB를 막을 수 있습니다. – rodrigo

+0

죄송합니다. 예, 단순화했습니다. – mythagel

2

내가 추측이가 아닌

다음이 일하는 것이 다시 벡터를 성장하려고하지 않았다을 알았다면 좋은 프로그래밍 방식. 벡터는 객체를 저장하는 책임이 있으며 더 큰 메모리 얼룩을 얻기 위해 메모리를 다시 기록 할 수 있습니다 ... 따라서 포인터가 더 이상 유효하지 않습니다 ...

1

vector::push_back은 주소가 유효하지 않은 이유 때문에 요소를 이동할 수 있습니다. 벡터에 메모리를 미리 넣기 전에 벡터에 메모리를 미리 넣고 reserve을 호출하거나 주소를 가져 오기 전에 푸시 작업을 마칠 때까지 기다릴 수 있습니다.

하지만 동적 메모리를 사용할 수 없다고 말합니다. vector은 동적 메모리를 사용합니다.

+0

벡터가 동적 메모리를 사용한다는 것을 알고 있지만,'new Foo()'와 같은 것을 할 수 없다는 것을 의미했습니다. 그러나 고마워, 나는 예비를 시험해 볼 것이다. – gsingh2011

관련 문제