首页 > 解决方案 > 程序在可区分联合的复制构造函数内崩溃

问题描述

所以我一直在尝试为我的项目创建一个有区别的工会。来自C,我认为这将是微不足道的......;)

该结构名为Message. 它有一个MessageType和 一个内部联合,它持有 aMessageGet或 a MessageSet

enum MessageType {
    MESSAGE_GET,
    MESSAGE_SET
};

struct MessageGet {
    std::string store_name;
    std::vector<uint8_t> key;
};

struct MessageSet {
    std::string store_name;
    std::vector<uint8_t> key;
    std::vector<uint8_t> value;
};

struct Message {
    MessageType type;

    uint64_t sender_id;    

    union U {
        U() : get() {}

        U(const U& other) {
            get = other.get;
            set = other.set;
        }

        ~U() {}

        U& operator=(const U& other) {
            set = other.set;
            get = other.get;
            return *this;
        }

        MessageGet get;

        MessageSet set;
    } as;

    Message() {}

    ~Message() {
        switch (type) {
            case MESSAGE_GET: {
                as.get.~MessageGet();
                break;
            }
            case MESSAGE_SET: {
                as.set.~MessageSet();
                break;
            }
        }
    }

    Message(MessageGet get, uint64_t sender_id) {
        type = MESSAGE_GET;
        as.get = get;
        sender_id = sender_id;
    }

    Message(MessageSet set, uint64_t sender_id) {
        type = MESSAGE_SET;
        as.set = set;
        sender_id = sender_id;
    }

    Message(const Message& other) {
        type = other.type;
        as = other.as;
        sender_id = other.sender_id;
    }

    Message& operator=(const Message& other) {
        type = other.type;
        as = other.as;
        sender_id = other.sender_id;
        return *this;
    }
};

该程序在我执行以下操作的代码中的其他地方崩溃:

Message message(MessageGet {std::move(store_name), std::move(key)}, sender);
messages.push_back(message); // messages is a local std::vector<Message>

它不会因异常而崩溃 - 只是崩溃。

我设法将其缩小到Message复制构造函数内部。之后,不知道是什么原因造成的。想法将不胜感激。

标签: c++crashunion

解决方案


    U(const U& other) {
        get = other.get;
        set = other.set;
    }

这总是set最后设置,使值get无效。当您设置联合的成员之一时,它会使所有其他成员无效。这就是使联合与结构不同的原因。

你在哪里:

    as = other.as;

您必须将其更改为仅复制有效成员。


推荐阅读