C ++ 14 - ошибка сегментации исправлена ​​путем вызова пустого метода в struct? - PullRequest
0 голосов
/ 25 ноября 2018

Так что все работало отлично, пока я не решил закомментировать метод печати (для отладки).Как только я это закомментировал, мой код начал вызывать ошибку.

Я предположил, что это потому, что я каким-то образом модифицировал что-то в своем методе печати, поэтому я закомментировал одну строку за раз, чтобы я мог найти, где это былопроисходит.Прокомментировав каждую строку в распечатке, я заметил, что ошибка будет возникать только тогда, когда я не вызывал метод печати (даже если он был полностью пустым!).

Итак, я сделал это:

void emptyMethod(Qclass c) {}

void Typechecker::initializeClasses(AST::Node *astRoot) {
     ...
        Qclass clazz;
     ...
        this->classes[clazz.name] = clazz;
        emptyMethod(clazz); // I have no idea why I have to do this, but it 
                               seg faults if I don't
     ...
}

Это исправляет мою ошибку сегмента.

Структуры, о которых идет речь:

struct Qclass; // forward declare
struct Qmethod {
    AST::Node *node; // pointer to the node in the tree

    // The reference to the containing class of a method is a pointer because
    // it may not be fully initialized when passed into any given Qmethod.
    // This is okay because we don't use *clazz until after all initialization is 
    complete.
    Qclass *clazz;

    std::string name;
    std::vector<std::string> init;
    std::map<std::string, std::string> type;
    std::vector<AST::Node*> stmts;
};

struct Qclass {
    AST::Node *node; // pointer to the node in the tree
    std::string name;
    std::string super;
    Qmethod constructor;
    std::vector<Qmethod> methods;

    // for use in init before use checking in non constructor methods
    std::vector<std::string> instanceVars; 
};

Где происходит ошибка сегмента:

bool Typechecker::initCheckStmt(Qmethod &method, AST::Node *stmt, bool isConstructor) {
    ...
    method.clazz->instanceVars.push_back(left->get(IDENT)->name); // seg faults here when not calling the empty method
    ...

    return true;
}

Ошибка ошибки сегмента:

#0  0x00007fffff1919b8 in std::__cxx11::basic_string<char,                 
std::char_traits<char>, std::allocator<char>                     
>::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const&) () from /usr/lib/x86_64-linux- 
gnu/libstdc++.so.6
#1  0x000000000041ab38 in void __gnu_cxx::new_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::construct<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#2  0x0000000000417dc6 in void std::allocator_traits<std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::construct<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#3  0x0000000000415b56 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#4  0x00000000004136b3 in Typechecker::initCheckStmt(Qmethod&, AST::Node*, bool) ()
#5  0x00000000004134b9 in Typechecker::getLeaves(Qmethod&, AST::Node*, std::vector<AST::Node*, std::allocator<AST::Node*> >&, bool) ()
#6  0x00000000004137c8 in Typechecker::initCheckQmethod(Qmethod&, bool) ()
#7  0x0000000000413a16 in Typechecker::initializeBeforeUseCheck() ()
#8  0x0000000000413d12 in Typechecker::checkProgram() ()
#9  0x0000000000426e7b in main ()

Я вижу, что это должно иметь какое-то отношение к вектору instanceVars, но я не понимаю, почему пустой вызов метода это исправит.Моя способность к поиску в Google не помогает мне, поэтому любые указатели будут очень благодарны.

(этот код предназначен для курса по компиляции)

1 Ответ

0 голосов
/ 25 ноября 2018

У вас есть какое-то неопределенное поведение.Ваша программа что-то делает - возможно, доступ к памяти за пределами допустимого, кто знает, - это отбрасывает вашу программу.В C ++, когда ваша программа делает это, все ставки отключаются для того, что она делает дальше, включая segfaulting.

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

Чтобы решить эту проблему, вам нужно взглянуть на остальную часть вашей программы, чтобы определить, где может быть проблема.Недостаточно одной линии, где она сломалась;Вы должны посмотреть до и после строки, где заканчивается segfaulting, а также то, что вы передаете в initializeClasses.

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