2014-06-08 2 views
2

저는 C# 프로그래머이고 이제 C++을 사용하여 작업을 수행합니다.포인터의 내용이 왜 변경됩니까?

pair<Point,double>* p=NULL; 
Sphere* sphere=NULL; 

for (int i=0;i<spheres.size();i++) 
{ 
    vector<pair<Point,double>> solution=findIntersection(Point(ray.origin),Point(ray.direction.x,ray.direction.y,ray.direction.z),spheres[i]); 

    if(solution.size()==0) 
     continue; 


    if(p==NULL || solution[0].second<p->second) 
    { 
     p=&solution[0]; 
     sphere=&spheres[i]; 
    } 
} 


if(p==NULL) 
    return backgroundColor; 
else 
{ 
    Color c=localIlluminate(p->first,*sphere); 
    return c; 
} 

내가 원하는 p.first 가장 작은 값을 가지고, 그리고 spherep를 얻기 위해 사용되는 cooresponding 구체합니다.

디버깅 후 코드가 작동하지 않습니다. 첫 번째 루프에서 p의 주소는 solution[0]이며, 값은 {(0,0), 0}이라고 가정합니다. 그런 다음 루프가 계속되고 i=1 일 때 솔루션 [0]이 {(1,2), 3}이되고 p의 값도 {(1,2), 3}이된다고 가정합니다.

p 값을 변경하지 않을 것으로 예상됩니다. 어떻게 수정해야합니까?

+0

다음 반복에서 사라질 요소에 대한 포인터를 저장합니다 (로컬 벡터가 대체되고 내부를 가리키고 있기 때문에). 포인터 대신 사본을 저장하십시오. –

답변

2

로컬 변수에 대한 참조를 로컬 변수가 선언 된 범위 밖에 저장합니다.

반복 할 때마다 solution은 더 이상 유효하지 않으므로 주소가 유효하지 않아야합니다. 당신이 실제로 포함 된 값을 복사 있도록, 당신은 값으로 변수를 지정해야합니다 예를 들어 필요한 얻으려면 :

pair<Point, double> p = std::make_pair(whatever, std::numeric_limits<double>::max()); 

for (...) 
{ 
    if (solution[0].second < p.second) 
    p = solution[0]; 
} 

주소 변경이 여러 가지 이유로 인해 발생할 수 있습니다,하지만 당신은 신경 안된다는 사실 이유를 이해하고, 이런 종류의 상황을 피하십시오. 당신의 오해는 C#이 가비지 콜렉션을 가지고있어서 solution[0]이 무효화되는 것을 막았 기 때문에 온다. C++의 경우 변수가 스택에 선언 될 때 사실이 아니다.

+0

C#에서 개체 유형은 null이거나 구체적인 값일 수 있습니다. 값이 null의 경우, 솔루션이 발견되지 않는 것을 나타냅니다. C++에서는 솔루션을 찾았는지를 결정하기 위해 하나 이상의 변수를 사용해야합니까, 아니면 바깥 값을 사용하여 루프 밖에서 더미 값을 확인해야합니까? – Gqqnbig

+1

@LoveRight nullable 유형이 필요한 경우 boost :: optional을 사용할 수 있지만이 경우 Jack이 제공하는 솔루션이 더 좋습니다. –

+0

@LoveRight : 사실 C#에서는 객체가 'null'이거나 힙에 할당 된 객체에 대한 포인터가 될 수 있습니다. C++에서 객체를 인스턴스화하는 두 가지 방법 (실제로는 더 많이), 힙에 할당하거나 스택에 할당 할 수 있습니다. 첫 번째 종류는 C#과 매우 유사하지만 후자는 하드웨어 스택 구현과 관련이 있습니다. 스택 객체는보다 효율적이며 가능한 경우 사용해야합니다. – Jack

2

p에 지정하면 & 해결책 [0]의 주소를 가리키고 있지만 루프의 다음 반복에서 변수가 흘러 나오고 새 변수가 만들어지고 p가 임의 항목이나 다른 것을 가리키게됩니다.

p에 복사본을 저장하는 것이 더 좋을 수 있으므로 p를 정규 변수로 만들고 할당하여 솔루션 [0]에 복사하십시오. 솔루션이 있는지를 판별하기 위해 다른 bool 변수를 가질 수 있습니다.

pair<Point,double> p; 
Sphere sphere; 
bool solutionFound = false; 

for (int i=0;i<spheres.size();i++) 
{ 
    vector<pair<Point,double>> solution=findIntersection(Point(ray.origin),Point(ray.direction.x,ray.direction.y,ray.direction.z),spheres[i]); 

    if(solution.size()==0) 
     continue; 


    if(!solutionFound || solution[0].second < p.second) 
    { 
     p=solution[0]; 
     sphere=spheres[i]; 
     solutionFound = true; 
    } 
} 


if(!solutionFound) 
    return backgroundColor; 
else 
{ 
    Color c=localIlluminate(p.first, sphere); 
    return c; 
} 
관련 문제