为什么函数调用后指针不为空?

时间:2011-10-14 14:42:58

标签: c++ pointers

我不经常使用C ++,我现在遇到使用Microsoft C ++指针的问题 我已经定义了一个半边数据结构。代码示例显示了结构的一部分。

struct edge
{
    HalfEdge    *he1;   // pointer to right halfedge
    HalfEdge    *he2;   // pointer to left halfedge 
    Edge        *nexte; // pointer to next edge
    Edge        *preve; // pointer to previous edge
};

struct halfedge
{
    Edge        *edg;   // pointer to parent edge
    Vertex      *vtx;   // pointer to starting vertex 
    Loop        *wloop; // back pointer to loop
    HalfEdge    *nexthe;// pointer to next halfedge
    HalfEdge    *prevhe;// pointer to previous halfedge
};

现在我已经将Edge的变量初始化为NULL 我在方法中使用edge。

void CDataStructureBuilder::create4VertFace(Face* f,Vertex* v1,Vertex* v2, Vertex* v3, Vertex* v4,Edge* e1,Edge* e2,Edge* e3,Edge* e4){
    Loop outerLoop;

    createHalfEdges(v1,v2,e1);  
    createHalfEdges(v2,v3,e2);
    createHalfEdges(v3,v4,e3);  
    createHalfEdges(v4,v1,e4);  


    outerLoop.lface = f;
    outerLoop.ledge = e1->he2;

    connectEdges(e1, e2);
    connectEdges(e2, e3);
    connectEdges(e3, e4);
    connectEdges(e4, e1);

如果我使用调试器,我看到e1的变量he1和he2包含0x000000。现在我调用以下函数。

void CDataStructureBuilder :: createHalfEdges(Vertex * v1,Vertex * v2,Edge * ed){         if(ed-> he2 == NULL){             HalfEdge * h = new HalfEdge();             h-> vtx = v1;             h-> edg = ed;             ed-> he2 = h;         }         if(!(ed-> he1)){             HalfEdge * h = new HalfEdge();             h-> vtx = v2;             h-> edg = ed;             ed-> he1 = h;         }     }

现在,如果我使用调试器,指针ed具有相同的地址,但变量he2和he1不再包含0x000000。它们包含0xccccccc。因此方法createHalfEdges中的if-condition ed-> he2 == NULL为false。

有人可以告诉我,我做错了吗?

附加信息:
create4VertFace的外部方法正在执行以下操作:

Vertex* vertices;
vertices = createVertices();

Edge* edges;
edges = createEdges();

create4VertFace(&bottom, &vertices[0], &vertices[1], &vertices[2], &vertices[3], &(edges[0]), &(edges[1]), &(edges[2]), &(edges[3]));

createedges中,我已按以下方式定义边缘。这可能是错误吗?

Edge* CDataStructureBuilder::createEdges(void){
    Edge edgelist[24]; 

    Edge e0t1 = {NULL,NULL,NULL,NULL};
    // ...
    edgelist[0] = e0t1;
    // ...
}

2 个答案:

答案 0 :(得分:5)

问题在于:

   HalfEdge h;
   ...
   ed->he2 = &h;
退出封闭块时,

h超出范围。因此,ed->he2在保持其值的同时变为dangling pointer

解决这个问题的一种方法是在堆上分配HalfEdge实例(使用new)。

编辑createEdges()看起来有同样的错误:它会创建指向e0t1的指针。后者存在于堆栈中,并在函数返回时超出范围。

答案 1 :(得分:1)

Visual C ++编译器使用0xCC来填充未初始化的数据。最有可能ed指向在堆栈上创建的临时对象,其内容稍后被销毁,并在下次调用时被覆盖。

请注意,ed->he2 = &h;也会获取临时对象h的地址,这与隐藏ed内容的错误相同。