如何为尚未初始化的工会成员分配内存

how can i allocate memory for a union member that haven't been initialized

本文关键字:成员 分配 内存 初始化      更新时间:2023-10-16

我有两个成员的工会。

union myUnion {
    std::wstring mem1;
    int mem2;
    myUnion(std::wstring in){
        this->mem1 = in;
    }
    myUnion(int in){
        this->mem2 = in;
    }
    myUnion(const myUnion& in){
        if(this->mem2){
            this->mem2 = in.mem2;
        }else{
            this->mem1 = in.mem1;
        }
    }
};
//and then I make a vector out of the union:
std::vector<myUnion> unions;
//but when I try to push_back:
unions.push_back(L"A");

它很快就会出现运行时错误: 0xC0000005:访问违规写入位置0xCCCCCCCC。当我尝试调试该程序时,我意识到 mem1 尚未分配内存。我真的不知道为什么会发生这种情况,我想知道如何解决它。

在C++中,union 不是一个非常自然的数据类型,因为它与构造函数和析构函数的整个C++思想并不自然地吻合。在 C++ 中创建联合时,它不会为其任何可能的类型调用构造函数,因为它们都将相互叠加编写。

所以这个构造函数

myUnion(std::wstring in){
    this->mem1 = in;
}

会崩溃,因为this->mem1字符串的生存期尚未启动。您必须使用类似的东西,在该地址使用放置 new 调用std::string ctor。稍后,如果更改数据类型,则必须确保在开始写入联合的其他字段之前也记住调用 dtor for this->mem1,否则会出现内存泄漏或损坏。

到目前为止,执行您尝试在C++中执行的操作的更简单方法是使用像boost::variant这样的变体类型,它将为您处理所有样板和所有详细信息。(如果您只使用没有 ctor 或 dtors 的普通类型,则可以使用联合。

typedef boost::variant<std::wstring, int> MyUnion;
std::vector<MyUnion> unions;
unions.push_back(L"A");

您的复制构造函数已损坏,因为...

if(this->mem2){

。对于除 0 以外的任何mem2值返回 true,如果联合实际上是用字符串构造的,那么 mem2 是来自 mem1 的前 sizeof mem2 个字节:很可能是非 0。 如果您希望类似联合的对象正确复制自身,通常需要将其包装在外部struct中添加一些积分/枚举类型来跟踪联合的当前数据类型。 其他行为,包括myUnion(wstring)构造函数和析构函数也存在缺陷。

在不调用未定义行为的情况下处理联合是很棘手的 - 最好改用boost::variant