为什么指针的内容会发生变化?

时间:2014-06-08 01:59:15

标签: c++

我是一名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具有最小值,sphere是用于获取p的相应范围。

调试后,我发现代码不起作用。在第一个循环中,p将被赋予solution[0]的地址,假设值为{(0,0),0}。然后循环继续,当i=1时,假设解[0]变为{(1,2),3},p的值也变为{(1,2),3}。

我不希望p的值发生变化。我该如何解决?

2 个答案:

答案 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 ++中是不正确的,当在堆栈上声明变量时。

答案 1 :(得分:2)

当你指定给p时,它指向&amp; solution [0]的地址,但是在循环的下一次迭代中,变量变为poof并且创建了一个新的并且p指向随机的东西或其他东西。< / 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;
}