Грешка при сегментиране при четене на файл/вход с getline

Опитвам се да разработя прост преглед на 3d модели, който трябва да може да чете файлове ред по ред във формат obj. Това изглеждаше много просто, но когато std::getline удари eof, програмата излиза с грешка в сегментирането.

Тук направих най-малкото количество код, което ми дава segfault (използвам std::cin тук, така че програмата ми да не приключи веднага, но всъщност имам шанс да въведа някои неща в нея и ръчно да въведа eof ):

std::string line;
while(std::getline(std::cin, line))
    {
        std::cout<<line;
    }

Друго нещо, което трябва да забележите е, че този код ще генерира само segfault, ако редът, съдържащ eof, е празен, в противен случай, ако eof се въведе на ред, съдържащ нещо друго, цикълът просто продължава.

Редактиране: Сега възпроизведох това с възможно най-малкия код:

main.cpp

#include <iostream>
#include "Model.h"

int main(int argc, char* argv[])
{

    std::string path = "/home/thor/Skrivebord/3d_files/Exported.obj";
    obj::Model(path.c_str());

    return 0;
}

Модел.h

#ifndef MODEL_H_INCLUDED
#define MODEL_H_INCLUDED

namespace obj
{
    class Model
    {
    public:
        Model(const char* path);
    };
}

#endif // MODEL_H_INCLUDED

Model.cpp

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <string>

namespace obj
{
    class Model
    {
    public:
        Model(const char* path);

    private:
        std::string name = ""; // Remove this line, and all works.
    };

    Model::Model(const char* path)
    {
        std::string line;

        while(std::getline(std::cin, line))
        {
            std::cout << line;
        }
    }
}

person Community    schedule 24.11.2013    source източник
comment
Просто направете while (getline(cin, line)) без условното eof().   -  person 0x499602D2    schedule 24.11.2013
comment
Вече опитах това и все още ми дава segfault.   -  person    schedule 24.11.2013
comment
След това ни покажете действителния си код.   -  person 0x499602D2    schedule 24.11.2013
comment
Няма нищо лошо в публикуваните два реда код. Какъвто и да е проблемът ви, той е в кода, който не сте публикували.   -  person john    schedule 24.11.2013
comment
Има щастлива среда между публикуването на почти никакъв код и публикуването на целия ви код. Започнете да премахвате неща от кода си, направете програмата все по-малка и по-малка, докато все още имате грешката, за която питате. Когато програмата е толкова малка, колкото можете да направите, но все още има грешка, публикувайте целия този код.   -  person john    schedule 24.11.2013
comment
Тук нещо сериозно не е наред. Не мога да тествам точния ви код, защото нямам C++11. Но няма начин това да се срине, както казвате. Кой компилатор използвате?   -  person john    schedule 24.11.2013
comment
Използвам gcc 4.8 на Ubuntu 12.04. И не мога да видя никаква част от кода, която използва C++11.   -  person    schedule 24.11.2013
comment
std::string name = "" е законен само в C++11. Тествах го без = "" и не се срина за мен (не е изненада).   -  person john    schedule 24.11.2013
comment
Сега го тествах и без = "" и все още дава segfault.   -  person    schedule 24.11.2013
comment
@Lillesort131 Добре сега го виждам, бях сляп. Ще отговоря след минутка.   -  person john    schedule 24.11.2013


Отговори (2)


Проблемът е, че вашият код има две противоречиви декларации на Model.

В Model.cpp имате

class Model
{
public:
    Model(const char* path);

private:
    std::string name = ""; // Remove this line, and all works.
};

но в Model.h имате

class Model
{
public:
    Model(const char* path);
};

Трябва да имате само една дефиниция на Model, поставете я в Model.h и #include "Model.h" в Model.cpp

person john    schedule 24.11.2013
comment
Кои точно части от кода трябва да преместя? Ако просто преместя самия клас, Model::Model(const char* path){ ... } ми дава грешка. - person ; 24.11.2013
comment
Просто преместете самия клас и добавете #include "Model.h" към Model.cpp. - person john; 24.11.2013
comment
Трябва да имате само една дефиниция на всеки клас. Поставете тази дефиниция в заглавен файл и #включете заглавния файл навсякъде, където имате нужда. Това е техниката, за да се уверите, че имате последователни дефиниции на класове във вашия код. - person john; 24.11.2013
comment
Благодаря ви, сега работи. Просто забравих да #include "Model.h. - person ; 24.11.2013

Това изглежда като грешка, въпреки че логиката е трудна за следване.

void Face::AddVertex(float x, float y, float z)
{
    if (vCnt > 3)
    {
        vertices[vCnt].SetPos(x, y, z);
        ++vCnt;
    }
    else
    {
        vertices.push_back(Vertex(x, y, z));
        ++vCnt;
    }
}

По-логично е с < не >, тъй като вашият vertices вектор първоначално е с размер 3

void Face::AddVertex(float x, float y, float z)
{
    if (vCnt < 3)
    {
        vertices[vCnt].SetPos(x, y, z);
        ++vCnt;
    }
    else
    {
        vertices.push_back(Vertex(x, y, z));
        ++vCnt;
    }
}
person john    schedule 24.11.2013