Форум программистов, компьютерный форум CyberForum.ru

Почему кидает SEHException? - C++

Восстановить пароль Регистрация
 
Zarc
0 / 0 / 0
Регистрация: 01.02.2012
Сообщений: 11
28.05.2013, 10:29     Почему кидает SEHException? #1
Здравствуйте! Ситуация такова: есть клас DCEL (рёберный список с двойной связностью). В нём два public метода: EdgesForVertex - возвращает список указателей на рёбра, смежные c данной вершиной; EdgesForFaces - возвращает список указателей на рёбра, ограничивающие данную грань.

По структуре оба метода одинаковы, но EdgesForVertex работает как положено, а EdgesForFaces кидает тот самый SEHException.

С обработкой исключений на с++ не очень знаком, от того ещё тяжелее разобраться, что к чему.

Использую VS2010.

Привожу код класа DCEL:

DCEL.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//Double connected edge list
 
#pragma  once
#ifndef DCEL_H
#define DCEL_H
 
#include <vector>
#include <list>
using namespace std;
 
namespace EDM 
{ 
    namespace Model 
    { 
        namespace TriangulationMethod
        {
            class TriangActor;
        }
    }
    namespace EDM_Graphics
    {
        class Point2F;
    }
}
 
using namespace EDM::EDM_Graphics;
using namespace EDM::Model::TriangulationMethod;
 
namespace EDM {namespace Logic { namespace Voronoi 
{
    class EdgeNode;
    typedef vector<EdgeNode> DCEL_EdgesT;
 
    class DCEL
    {
    public:
 
        DCEL_EdgesT edges;
 
        DCEL(size_t size);
        ~DCEL();
 
        // Returns the list of pointers to adj edges enumerated in counterclockwise direction for vertex.
        list<EdgeNode*> EdgesForVertex(const Point2F &vertex);
 
        // Returns the list of pointers to adj edges enumerated in clockwise direction for face.
        list<EdgeNode*> EdgesForFaces(const TriangActor &face);
 
    private:
        EdgeNode* FirstCCWEdgeForVertex(const Point2F &vertex);
        EdgeNode* NextCCWEdgeForVertex(const Point2F &vertex, EdgeNode *nextEdge);
 
        EdgeNode* FirstCWEdgeForFace(const TriangActor &face);
        EdgeNode* NextCWEdgeForFace(const TriangActor &face, EdgeNode *nextEdge);
    };
 
}}}
 
#endif
DCEL.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "Point2F.h"
#include "TriangActor.h"
#include "EdgeNode.h"
#include "DCEL.h"
 
using namespace EDM::EDM_Graphics;
using namespace EDM::Model::TriangulationMethod;
using namespace EDM::Logic::Voronoi;
 
DCEL::DCEL(size_t size)
{
    edges.reserve(size);
}
 
DCEL::~DCEL()
{
    /*for (DCEL_EdgesT::iterator edgeIter = edges.begin(); edgeIter != edges.end(); edgeIter++)
    {
        delete *edgeIter;
    }*/
    edges.clear();
}
 
list<EdgeNode*> DCEL::EdgesForVertex(const Point2F &vertex)
{
    EdgeNode *nextEdge = FirstCCWEdgeForVertex(vertex);
    
    if (!nextEdge)
    {
        //TODO: throw correct exception
        throw -1;
    }
    
    EdgeNode *startEdge = nextEdge;
    list<EdgeNode*> adjEdges = list<EdgeNode*>();
    adjEdges.push_back(nextEdge);
 
    nextEdge = NextCCWEdgeForVertex(vertex, nextEdge);
 
    while(*nextEdge != *startEdge)
    {
        adjEdges.push_back(nextEdge);
        nextEdge = NextCCWEdgeForVertex(vertex, nextEdge);
    }
 
    return adjEdges;
}
 
EdgeNode* DCEL::FirstCCWEdgeForVertex(const Point2F &vertex)
{
    for (size_t edgeCntr = 0; edgeCntr < edges.size() ; edgeCntr++)
    {
        if ((*(edges[edgeCntr].vBegin) == vertex) || (*(edges[edgeCntr].vEnd) == vertex))
        {
            return &(edges[edgeCntr]);
        }
    }
    return nullptr;
}
 
EdgeNode* DCEL::NextCCWEdgeForVertex(const Point2F &vertex, EdgeNode *nextEdge)
{
    if (*(nextEdge->vBegin) == vertex)
    {
        return nextEdge->p1;
    }
    else
    {
        return nextEdge->p2;
    }
}
 
list<EdgeNode *> DCEL::EdgesForFaces(const TriangActor &face)
{
    EdgeNode *nextEdge = FirstCWEdgeForFace(face);
 
    if (!nextEdge)
    {
        //TODO: throw correct exception
        throw -1;
    }
 
    EdgeNode *startEdge = nextEdge;
    
        //////////////////////////////////////////////////////////////////////////
    //SEHExeption при создании списка
    list<int> intlist;        
    intlist.push_back(1);
    intlist.push_back(2);
    intlist.push_back(3);
    intlist.push_back(4);
 
        //////////////////////////////////////////////////////////////////////////
    //та же ошибка
    list<EdgeNode *> adjEdges;
    adjEdges.push_back(nextEdge);
 
    nextEdge = NextCWEdgeForFace(face, nextEdge);
 
    while(*nextEdge != *startEdge)
    {
        adjEdges.push_back(nextEdge);
        nextEdge = NextCWEdgeForFace(face, nextEdge);
    }
 
    return adjEdges;
}
 
EdgeNode* DCEL::FirstCWEdgeForFace(const TriangActor &face)
{
    for (size_t edgeCntr = 0; edgeCntr < edges.size() ; edgeCntr++)
    {
        if ((*(edges[edgeCntr].fLeft) == face) || (*(edges[edgeCntr].fRight) == face))
        {
            return &(edges[edgeCntr]);
        }
    }
    return nullptr;
}
 
EdgeNode* DCEL::NextCWEdgeForFace(const TriangActor &face, EdgeNode *nextEdge)
{
    if (*(nextEdge->fLeft) == face)
    {
        return nextEdge->p1;
    }
    else
    {
        return nextEdge->p2;
    }
}
Ошибка вылетает в методе EdgesForFaces, когда пытаюсь создать список adjEdges. Для интереса попробовал просто заполнить интовский список, так ошибка стала появляться и в строке
C++
1
list<int> intlist;
Хотя, повторюсь, в схожем методе EdgesForVertex, список рёбер заполнился, как я хотел.

Если надо, выложу другие части кода.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.05.2013, 10:29     Почему кидает SEHException?
Посмотрите здесь:

Почему не взяли на обучение в CQG, на сайте нашел испытательное задание, сделал и отослал. Не взяли и не объяснили почему. Хочу услышать мнения. C++
Почему MS-DOS не любит кириллицу ? (Или почему она не любит меня ?) C++
SEHException не обработано C++
C++ SEHException при заполнении вектора
Участок B кода выполняется позже, чем участок A кода, но почему-то B влияет на работоспособность A! Почему? C++
C++ VS кидает исключение при повторном освобождении памяти
C++ IDE wxDev-C++, при создании кнопки на форме она почему-то становится во весь экран, почему?
C++ Почему выводится в виде таблицы и почему не работает сортировка

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Zarc
0 / 0 / 0
Регистрация: 01.02.2012
Сообщений: 11
29.05.2013, 16:32  [ТС]     Почему кидает SEHException? #2
Ошибку исправил, но до конца не понял, почему она выскакивала. Так как никто не ответил, пишу в чём была причина, может кому поможет.

В методе FirstCWEdgeForFace класса DCEL, с первого поста в цикле сравнивались объекты класса TriangActor, в котором был переопределён operator==() таким образом, что он вызывал operator==() базового класса Node. Привожу код класса TriagActor:

TriagActor.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#pragma once
#ifndef TRIANGACTOR_H
#define TRIANGACTOR_H
 
#include <list>
#include "Node.h"
 
namespace EDM { namespace Model { namespace TriangulationMethod
{
    class TriangActor: public Node
    {
    public:
        //list<Node*> *m_neighbours; // до ошибки был указатель на список указателей
        list<Node*> m_neighbours;
 
        TriangActor();
        TriangActor(CoordT _coordT, Vector2fT _vel, double _radius);
        TriangActor(CoordT _coordT, Vector2fT _vel, double _radius, EventT *_evnt, double _massa = 1.0);
        ~TriangActor();
 
        bool operator==(const TriangActor obj);
 
        static bool CompareByAscendingX(const TriangActor &a, const TriangActor & b)
        {
            return a.coord.x < b.coord.x;
        }
    };
}}}
 
#endif
TriagActor.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "TriangActor.h"
 
using namespace EDM::Model::TriangulationMethod;
 
TriangActor::TriangActor() : Node()
{
    //m_neighbours = new list<Node*>();
}
 
TriangActor::TriangActor(CoordT _coord, Vector2fT _vel, double _radius)
    : Node(_coord, _vel, _radius)
{
    //m_neighbours = new list<Node*>();
}
 
TriangActor::TriangActor(CoordT _coord, Vector2fT _vel, double _radius, EventT *_evnt, double _massa)
    : Node(_coord, _vel, _radius, _evnt, _massa)
{
    //m_neighbours = new list<Node*>();
}
 
TriangActor::~TriangActor()
{
    //delete m_neighbours;
}
 
bool TriangActor::operator==(const TriangActor obj)
{
    return Node::operator ==(obj);
}
Строки до ошибки - закомментированные.
До ошибки в классе был указатель на список указателей, который удалялся в деструкторе.
Так вот, как я понял, при упомянутом выше сравнении в строке

C++
1
if ((*(edges[edgeCntr].fLeft) == face) || (*(edges[edgeCntr].fRight) == face))
неявно дважды создавался объект TriagActor через оператор копирования по-умолчанию (указатели fLeft и fRight, соответственно), а после, при удалении, вызывался деструктор, который удалял указатель m_neighbours. В этом месте как-то портилась куча и блокировалась для размещения в ней в дальнейшем объектов. Поэтому в методе EdgesForFaces с первого поста и нельзя было создать что либо после вызова метода FirstCWEdgeForFace.

Как-то так. Объяснил скорее сам себе, если что понял не так - подскажите, а то до конца не разобрался, почему именно портилась куча (ну удалил указатель, что тут такого...).
Yandex
Объявления
29.05.2013, 16:32     Почему кидает SEHException?
Ответ Создать тему
Опции темы

Текущее время: 12:42. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru