匿名共用体を使用してQVariant
呼び出されるようなクラスを実装しています。Variant
class Variant
{
public:
// …
~Variant();
// …
private:
Type _type;
union
{
int _int;
uint64_t _uint64;
float _float;
void* _ptr;
};
};
次のようにメンバーVariant::~Variant()
を削除しようとすると、セグメンテーション違反が発生します。Variant::_ptr
String*
Variant::~Variant()
{
if (_type == Type::String)
delete reinterpret_cast<String*>(_ptr);
else if (_type == Type::Date)
delete reinterpret_cast<Date*>(_ptr);
// …
}
これは次のように割り当てられます。
Variant::Variant(const String& str)
: _type(Type::String),
_ptr(new String(str))
{}
興味深いのは、GDB のデストラクタ スタック フレームで、ユニオン メンバーにはアクセスできないが、Variant::_type
メンバーにはアクセスできることです。
(gdb) frame
#0 0x0000000000527700 in Variant::~Variant (this=0x7fffec0337a0, __in_chrg=<optimized out>) at Sources/Types/Variant.cpp:85
85 delete reinterpret_cast<String*>(_ptr);
(gdb) p _ptr
No symbol "_ptr" in current context.
(gdb) p _int
No symbol "_int" in current context.
(gdb) p _float
No symbol "_float" in current context.
(gdb) p _type
$2 = Variant::String
ユニオンは既に削除されているようで、_ptr
アクセスできないものを削除しようとして segfautl します。しかし、なぜ?