C++ 14 - 通过在结构上调用空方法修复分段错误?

问题描述 投票:0回答:1

所以一切都很顺利,直到我决定注释掉打印方法(用于调试)。一旦我注释掉它,我的代码就开始出现分段错误。

我认为这是因为我以某种方式修改了打印方法中的某些内容,所以我一次注释掉一行,这样我就可以找到它发生的位置。在对打印输出中的每一行进行注释后,我注意到只有当我没有调用打印方法时才会出现段错误(即使它完全是空的!)。

所以我这样做了:

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 向量有关,但我不明白为什么空方法调用会修复它。我的谷歌搜索能力根本没有帮助我,所以任何指示将非常感激。

(此代码用于编译器课程)

c++ struct segmentation-fault stdvector
1个回答
0
投票

你自己有一些未定义的行为。你的程序正在做一些事情——也许是越界内存访问,谁知道呢——这会导致你的程序崩溃。在 C++ 中,当您的程序执行此操作时,接下来执行的所有操作都将失败,包括段错误。

那个空方法调用是隐藏错误,但它不是修复错误。正如您正确指出的那样,该方法调用不应影响它是否出现段错误。这样做的原因是由于未定义的行为。

要解决这个问题,您需要查看程序的其余部分以确定哪里可能存在问题。仅断掉的一根线是不够的;您应该查看最终出现段错误的行的前后,以及您要传递给的内容

initializeClasses

© www.soinside.com 2019 - 2024. All rights reserved.