2013-11-25 4 views
-1

Visual Studio 2010에서 포인터에 대한 포인터를 맵에 할당하는 while 문을 만듭니다. 예 :while 문에서 포인터에 포인터를 생성합니다.

std::map<int,std::tuple<int,std::string>** > dmap; 
     int i=0; 
     while (i<3){ 

      std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test")); 
      dmap[i] = &t; 
      dmap[i + 1 ] = &t; 
      i++; 
     } 
. 
. 
.  
for (auto it = d.begin();it!=d.end();++it) 
    { 
     if(*(it->second) != nullptr){ 
      delete *(it->second); 
      *(it->second) = nullptr; 
     } 


    } 

문제는 &t의 주소는 항상 내가 마지막 *t 값을 입력 한 모든 키에 대한 동일한 그래서지도가 항상 포함 말 것입니다.

무엇이 문제입니까? (해결 된)

[편집] 이제 불완전하기 전에 코드 beacause를 수정합니다. nullptr을 삭제하지 않으려면 포인터 포인터가 있어야합니다. 안 그래요?

+2

'dmap [i] = t;'대신에 t는 로컬 변수이므로 주소가 루프에서 동일하다는 것이 정상입니다. Btw a는 잠시 동안 이보다 더 좋으며 줄이 더 쉽습니다. – Thomas

+0

맞아, 고마워. – user3032420

+0

문제는 코드를 제대로 들여 쓰지 않았기 때문입니다! –

답변

0

글쎄, t의 주소는 스택에 저장된 로컬 변수이기 때문에 항상 동일합니다. 블록에 들어갈 때마다 t은 같은 자리에 할당됩니다 (귀하의 while 본문에서 벗어나면 t이 파괴됩니다).

대신 힙에 할당해야합니다 (실제로 원하는 경우).

std::tuple<int,std::string>** t = new std::tuple<int,std::string>*(); 
*t = new std::tuple<int,std::string>(10+i,std::string("test")); 
dmap[i] = t; 

당신이 달성하려고하는 것을 볼 수 있지만, 더 나은 해결책이 될 것입니다 :

std::map<int,std::tuple<int,std::string>* > dmap; 
    int i=0; 
    while (i<3){ 

     std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test")); 
     dmap[i] = t; 
     i++; 
    } 

대신 스마트 포인터 원료를 사용하는 것이 더 나은.

값을 기준으로 개체를 저장하는 것이 더 좋습니다 (전혀 포인터가 없습니다).

3

로컬 변수 t에 대한 포인터를 맵에 두는 것이 문제입니다. 각 루프가 끝나면 t이 삭제되고 포인터가 더 이상 유효하지 않습니다.

왜 포인터를 사용하고 있는지 전혀 알지 못합니다. 포인터에 대한 포인터는 말할 것도 없습니다. 당신은 아마지도에서 튜플 자신을 데려 가고 싶다는 왜 std::tuple<int,std::string>**에 관심이

std::map<int,std::tuple<int,std::string>> dmap; 
for (int i = 0; i<3; ++i){ 
    dmap[i] = {10+i, "test"}; 
} 
0

입니까?

std::tuple<int,std::string>*으로 충분하지 않습니까?

std::map<int,std::tuple<int,std::string>* > dmap; 
    int i=0; 
    while (i<3){ 

     std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test")); 
     dmap[i] = t; 
     i++; 
    } 
1

은 내가 이런 말을위한

죄송지도에 포인터에 대한 포인터를 할당하는 동안 문을 만들 수 있지만 당신은 사실보다 더 큰 문제가있는 것처럼 나에게 소리 t는 동일합니다 (이 모양은 xy problem과 같습니다).

는 이러한 대안 중 하나 (순서대로) 고려 :

  • 저장 값하여 튜플

  • 저장 한 포인터하여 튜플 (포인터로 "보다 더 나은,"값에 의해 "보다 더 포인터로 ").이렇게 할 수 있다면 튜플에 대한 포인터에 대한 포인터 맵이 실제로 필요한 경우 std::shared_ptr<std::tuple<...>> 이상의지도를 선언하는 것이 좋습니다. 내부적으로 포인터에 대한 스마트 포인터처럼 작동하는 최소한의 프록시 객체를 만드는 것이 좋습니다. 당신에게 안전한 방식으로 할당)하고 외부에서 정기적 인 유형처럼 (그리고지도를 적절하게 재 선언).

당신이 정말로 (어떤 이유로) 튜플에 대한 포인터에 대한 포인터의지도를 필요로하는 경우 는

어느 쪽이든, 할당은 다음과 같이 수행해야합니다 : 당신이 추가 한

std::map<int,std::tuple<int,std::string>**> dmap; 
int i=0; 
while (i<3) { 
    *dmap[ i ] = new std::tuple<int,std::string>{10 + i, "test"}; 
    ++i; 
} 

(방법 맵에 대한 동일한 로컬 (스택) 변수의 주소로, 로컬 함수를 종료 한 후에 정의되지 않은 동작을 유발할 수 있습니다.

관련 문제