2015-08-08 3 views
-1

Моя программа продолжает выдавать ошибку «[project] .exe« перестала работать ». После некоторой отладки линииC++ Ошибка сегментации

HitInfo hitInfo = (*it)->intersection(ray);

дает мне Signal : SIGSEGV:Segmentation fault, после чего (если снова нажав на резюме) сбои программы. Я читал, что эта ошибка может быть вызвана нулевым указателем, пытаясь получить доступ к памяти только для чтения и указывая на то, что больше не существует. Но я не могу найти точную проблему в моем случае.

Мой код выглядит следующим образом

HitInfo Mesh::intersection(const Ray & ray){ 
    HitInfo bestHitInfo(DBL_MAX); 
    for(std::vector<IFace*>::iterator it = faces.begin(); it != faces.end(); ++it) { 
     HitInfo hitInfo = (*it)->intersection(ray); 
     if(hitInfo.getT() < bestHitInfo.getT()){ 
      bestHitInfo = hitInfo; 
     } 
    } 
    bestHitInfo.setHitMaterial(Material(mtrl)); 
    return bestHitInfo; 
} 

Функция intersection(ray) не делает и не получить доступ в соответствующем классе, он просто бросает ошибку, когда он пытается передать эту строку кода.

Функция intersection(const Ray & ray) наследуется несколько раз, но поскольку она никогда не получает доступа, а не в родительском или дочернем классе, я не думаю, что это проблема.

Любая помощь в том, почему эта ошибка возникает или на что было бы лучшим способом найти ее было бы здорово.

---- EDIT ----

Это метод, который добавляет FlatFaces моих граней вектора. FlatFaces является подклассом IFace. Логика в создании лиц правильна и, возможно, не полезна для вопроса, но добавила все, чтобы быть уверенным.

void Mesh::readFile(const std::string & filename){ 
    std::ifstream inf(filename.c_str()); 
    if (!inf) { 
     std::cout << "Mesh file " << filename << " could not be opened!\n"; 
     exit(1); 
    } 
    int vertices, vectors, faces; 
    inf >> vertices >> vectors >> faces; 

    for(int n = 0; n < vertices; n++){ 
     double a,b,c; 
     inf >> a >> b >> c; 
     verts.push_back(Point(a, b, c)); 
    } 
    for(int n = 0; n < vectors; n++){ 
     double x,y,z; 
     inf >> x >> y >> z; 
     norms.push_back(Vector(x, y, z)); 
    } 
    for(int n = 0; n < faces; n++){ 
     int a; 
     inf >> a; 
     std::vector<Point> facesVerts; 
     std::vector<Vector> faceNorms; 
     for(int n =0; n < a; n++){ 
      double point; 
      inf >> point; 
      facesVerts.push_back(verts[point]); 
     } 
     for(int n = 0; n < a; n++){ 
      double norm; 
      inf >> norm; 
      faceNorms.push_back(norms[norm]); 
     } 
     FlatFace face = FlatFace(&verts[facesVerts[0]], &verts[facesVerts[1]], &verts[facesVerts[2]], norms[faceNorms[0]]); 
     this->faces.push_back(&face); 
    } 
+0

Вы, кажется, забыли, чтобы задать вопрос. – rottenoats

+1

Просто по объявлению этого итератора я бы точно подозревал, что вы упомянули: оборванный указатель и неопределенный указатель, или прямо-nullptr. Я уверен, что есть причина, по которой вы не используете 'std :: vector >' (или какой-либо другой класс интеллектуальных указателей). Но для моей жизни я не могу придумать, что это за причина. Ваш отладчик - ваш лучший друг прямо сейчас. *Используй это*. – WhozCraig

+0

Мне не очень удобно (пока) с отладкой C++, началось C++ пару дней назад, и я нахожу очень мало информации о переменной (по сравнению с java) очень раздражающей. У меня нет причин использовать этот итератор над любым другим, это часть кода, предоставленная в курсе, который я следую. Что заставляет задуматься о том, что в нем есть ошибка, даже странная ... В настоящее время застряла с отладкой в ​​'found where, но не знаю почему' – ThomasS

ответ

2
FlatFace face = FlatFace(&verts ... 

будет выделено на стеке. Вы добавляете адрес объекта в стек к вашему вектору. Когда вы позже перебираете свой вектор, этот адрес больше недействителен, потому что объект больше не находится в стеке.

Вы можете использовать вектор над общими указателями (std::vector<std::shared_ptr<FlatFace>>)

+0

Есть ли способ не иметь адрес более недействительным без изменения типа вектора, который я использую? Я действительно не понимаю, как объект находится или нет в стеке. Объект face должен быть сохранен, и вектор должен иметь указатели только на те объекты лица. – ThomasS

+0

Вы можете использовать ключевое слово 'new' для создания объекта в куче. Но вы должны удалить память самостоятельно (с помощью 'delete'). Вместо 'FlatFace face = FlatFace' вы пишете' faces.push_back (новый FlatFace (ваши аргументы); '. Не забудьте удалить объект позже. Это можно сделать, когда вам больше не нужен объект (' delete pointer_to_your_face') ... Я бы порекомендовал вам прочитать учебник по использованию стека/кучи на C++. – Hamdor

+0

Большое спасибо! У меня все еще есть проблемы с концепцией «новый» в C++, он настолько отличается от java. найдите хороший учебник. – ThomasS

Смежные вопросы