When creating a set of objects representing the multiple parts of an INI file, I faced a problem. The object representing a value in an INI file, representing in my code by a class having several variant variables, thanks to an anonymous union. The only problem, when assigning one of the instances of this class with another or when calling the constructor that takes an input string the program throws an exception by access violation and thus access to a part memory that is not allowed in the program.
I traced the problem with the debugger and it took me to the assignHelper function.
Here is the complete code of the class:
class YIniValue
{
public:
enum Type
{
Boolean = 0x0, //!< Boolean (true or false) value.
Number = 0x1, //!< Decimal or exponential value.
String = 0x2, //!< String value.
Undefined = 0x80, //!< Undefined value.
};
YIniValue(YIniValue::Type = YIniValue::Undefined);
YIniValue(bool value);
YIniValue(int value);
YIniValue(double value);
YIniValue(const std::string& value);
YIniValue(const char* value);
YIniValue(const YIniValue& other);
YIniValue(YIniValue&& other);
~YIniValue();
YIniValue& operator=(const YIniValue& other);
YIniValue& operator=(YIniValue&& other);
bool operator==(const YIniValue& other) const;
bool operator!=(const YIniValue& other) const;
inline Type type() const { return _type; }
inline bool isBoolean() const { return type() == YIniValue::Boolean; }
inline bool isNumber() const { return type() == YIniValue::Number; }
inline bool isString() const { return type() == YIniValue::String; }
inline bool isUndefined() const { return type() == YIniValue::Undefined; }
inline bool toBoolean(bool defaultValue = false) const
{ return (isBoolean()) ? _bool : defaultValue; }
inline double toNumber(double defaultValue = 0.0) const
{ return (isNumber()) ? _double : defaultValue; }
inline std::string toString(const std::string& defaultValue = std::string()) const
{ return (isString()) ? _string : defaultValue; }
inline operator bool() { return toBoolean(); }
inline operator int() { return (int)std::round(toNumber()); }
inline operator double() { return toNumber(); }
inline operator std::string() { return toString(); }
inline operator const char*() { return toString().c_str(); }
private:
void assignHelper(const YIniValue& value);
bool comparaisonHelper(const YIniValue& value) const;
union
{
bool _bool;
double _double;
std::string _string;
};
Type _type;
};
And this is the code of the function assignHelper()
which is called at the copy constructor and the operator =. The _type
variable is assigned just before the function is called:
void YIniValue::assignHelper(const YIniValue & value)
{
switch (value.type()) {
case YIniValue::Boolean: _bool = value._bool; break;
case YIniValue::Number: _double = value._double; break;
case YIniValue::String: _string = value._string; break;
case YIniValue::Undefined: break;
default: break;
}
}
The problem occurs on line 5. However, the exception is thrown from std::char_races <char>::move(char *, char const *, const unsigned int)
from the standard library.
I use the Visual Studio C++ 2017 compiler.
Thank you in advance for your answer and your clarification
Aucun commentaire:
Enregistrer un commentaire