Почему указатель не равен нулю после вызова функции? - PullRequest
0 голосов
/ 14 октября 2011

Я не часто использую 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.
Я работаю с краем в методе.

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);

Если я использую отладчик, я вижу, что переменные he1 и he2 в e1 содержат 0x000000. Теперь я вызываю следующую функцию.

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

Теперь, если я использую отладчик, указатель ed имеет тот же адрес, но переменные he2 и he1 больше не содержат 0x000000. Они содержат 0xccccccc. Поэтому условие if ed-> he2 == NULL в методе createHalfEdges имеет значение 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 ]

5 голосов
/ 14 октября 2011

Проблема здесь:

   HalfEdge h;
   ...
   ed->he2 = &h;

h выходит из области видимости при выходе из ограждающего блока. В результате ed->he2, сохраняя свое значение, становится висящим указателем .

Один из способов исправить это - выделить экземпляр HalfEdge в куче (используя new).

edit: Похоже, createEdges() имеет ту же ошибку: создает указатель на e0t1. Последний живет в стеке и выходит из области видимости, когда функция возвращается.

1 голос
/ 14 октября 2011

0xCC используется компилятором Visual C ++ для заполнения неинициализированных данных. Скорее всего, ed указывал на временный объект, который был создан в стеке, а его содержимое позже было уничтожено и перезаписано во время следующих вызовов.

Обратите внимание, что ed->he2 = &h; также принимает адрес временного объекта h, это та же ошибка, что и винты ed.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...