简体   繁体   English

添加异常后的奇怪行为

[英]Odd behavior after adding exceptions

I added some exception handling into some functions in my Project. 我在项目中的一些函数中添加了一些异常处理。 Before adding the error handling the program was working normally. 在添加错误处理之前,程序正常运行。 After adding the exceptions I now get garbage values in the constructor and mutator parameters and I'm not sure where its coming from. 添加异常后,我现在在构造函数和mutator参数中得到垃圾值,我不确定它的来源。 Some of the functions are called in no other location than the constructor, so I have no idea where they are getting the garbage data from. 有些函数在构造函数之外的其他位置调用,所以我不知道它们从哪里获取垃圾数据。

I also checked for memory leaks with valgrind and some debugging with gdb, but didn't find anything. 我还检查了valgrind的内存泄漏和gdb的一些调试,但没有找到任何东西。 I'm at my wits end. 我的智慧结束了。 I have attached a sample of the constructor cpp below and one of the mutators with the exception handling. 我已经附加了下面的构造函数cpp的示例和一个带有异常处理的mutator。

Protofield.cpp Protofield.cpp

ProtoField::ProtoField(std::string t_name, std::string t_abbreviation, FieldType t_type, Base t_base, int t_mask, std::string t_description, int t_offset, int t_length){
    try{
        setName(t_name);
        setAbbreviation(t_abbreviation);
        setType(t_type);
        setBase(t_base);
        setMask(t_mask);
        setDescription(t_description);
        setOffset(t_offset);
        setLength(t_length);
        m_valueString = std::map<int, std::string>();
    }
    catch(std::runtime_error e){
        std::cerr<<"Error in ProtoField Constructor"<<std::endl;
        std::cerr<<e.what()<<std::endl;
        return;
    }
}
/*Removed for brevity*/
void ProtoField::setMask(int t_mask){
    if(mask != 0){
        std::stringstream ss;
        ss<<"Field " << m_abbreviation << " mask previously set: "<<m_mask;
        throw std::runtime_error(ss.str());
    }
    else{
        m_mask = t_mask;
    }
    return;
}
/*Removed for brevity*/

ProtoField.hpp ProtoField.hpp

class ProtoField{
    private:
        std::string m_name;
        std::string m_abbreviation;
        FieldType m_type;
        Base m_base;
        int m_mask;
        std::string m_description;
        int m_offset;
        int m_length;
        std::map<int, std::string> m_valueString;
    public:
        ProtoField(
            std::string t_name = "",
            std::string t_abbreviation = "",
            FieldType t_type = FieldType::ft_invalid,
            Base t_base = Base::invalid,
            int t_mask = 0,
            std::string t_description = "", 
            int t_offset = -1,
            int t_length = -1
        );

        std::string getName();
        std::string getAbbreviation();
        FieldType getType();
        Base getBase();
        int getMask();
        std::string getDescription();
        int getOffset();
        int getLength();
        std::map<int, std::string> getValueString();

        void setName(std::string t_name);
        void setAbbreviation(std::string t_abbreviation);
        void setType(FieldType t_type);
        void setType(std::string t_typestr);
        void setBase(Base t_base);
        void setBase(std::string t_basestr);
        void setMask(int t_mask);
        void setDescription(std::string t_description);
        void setOffset(int t_offset);
        void setLength(int t_length);
        void addValueString(int t_key, std::string t_value);
        void removeValueString(int t_key);

        //other functions
        std::string to_string();
    };

I feel as though its also worth mentioning, only integers appear to be affected. 我觉得它也值得一提,只有整数似乎受到影响。 The other values including strings and enums seem to remain consistent with their previous behaviors. 包括字符串和枚举在内的其他值似乎与之前的行为保持一致。 So in the class shown, only the mask, offset, and length show odd behaviors. 因此在所示的类中,只有蒙版,偏移和长度显示奇怪的行为。

Edit: For more detail where the constructor is called I included the two functions I know of here. 编辑:有关构造函数调用的更多细节,我包含了我在这里知道的两个函数。

void parser::parseFields(ProtoData& t_data, ptree::ptree t_subtree){
        try{
            std::vector<ProtoField> fields;
            for(auto val : t_subtree.get_child("")){
                ProtoField field;
                parseField(t_data, field, val.second);
                fields.push_back(field);
            }
            for(auto field:fields){
                t_data.addField(field);
            }
        }
        catch(ptree::ptree_bad_path error){
            std::cerr<<"Bad Path to Fields"<<std::endl;
        }
        catch(ptree::ptree_bad_data error){
            std::cerr<<"Bad Data to fields"<<std::endl;
        }
    }

    void parser::parseField(ProtoData& t_data, ProtoField& t_field, ptree::ptree t_subtree){
        try{
            t_field.setAbbreviation(t_subtree.get<std::string>("abbreviation"));
            t_field.setName(t_data.getName() + "_" + t_field.getAbbreviation());
            t_field.setBase(t_subtree.get<std::string>("base", "none"));
            t_field.setType(t_subtree.get<std::string>("type"));
        }
        catch(ptree::ptree_bad_path error){
            std::cerr<<"Bad Path to Field"<<std::endl;
        }
        catch(ptree::ptree_bad_data error){
            std::cerr<<"Bad Data to field"<<std::endl;
        }
    }

Your constructor does not initialize m_mask . 您的构造函数不初始化m_mask You then call setMask , which reads this yet-to-be-initialzed value (assuming that the if(mask != 0) line should be if(m_mask != 0) ). 然后调用setMask ,它读取这个尚未初始化的值(假设if(mask != 0)行应为if(m_mask != 0) )。 This is Undefined Behavior. 这是未定义的行为。 The value read could be anything. 读取的值可以是任何值。 When it is a nonzero value, the exception will be thrown. 当它是非零值时,将抛出异常。

The solution is to either initialize m_mask before calling setMask , or assign to m_mask directly in the constructor and not call the helper function. 解决方案是在调用setMask之前初始化m_mask ,或者直接在构造函数中分配m_mask而不调用辅助函数。 (And since the constructor sets the mask, which can only be done once, why does that function even need to exist?) (并且由于构造函数设置了掩码,只能执行一次,为什么该函数甚至需要存在?)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM