在类的联合内部访问映射会产生分割错误

Accessing map inside union inside class gives segmentation fault

本文关键字:分割 错误 映射 访问 内部      更新时间:2023-10-16

我正在尝试创建一个包含一种类型或另一种类型的映射的类,因此我决定使用匿名联合。但是当我试图访问映射时,我的代码给出了一个分段错误(在这种情况下,我在构造函数和析构函数中都得到了一个分段错误):

#include <map>
#include <string>
#include <iostream>
class Foo
{
    private:
        union
        {
            std::map<std::string, int> ints;
            std::map<std::string, std::string> strings;
        };
        bool fooContainsInts;
    public:
        Foo(bool containsInts) : fooContainsInts(containsInts) 
        {
            if (containsInts) {ints = std::map<std::string, int>();}
            else {strings = std::map<std::string, std::string>();}
        }
        ~Foo()
        {
            if (fooContainsInts) {ints.clear();}
            else {strings.clear();}
        }
};  
int main() 
{
    std::cout << "No segfault here!" << std::endl;
    Foo foo(true);
    std::cout << "This line doesn't get printed" << std::endl;
    return 0;
}

我建议模板化类型而不是联合,但这可能会对您有所帮助。

http://en.cppreference.com/w/cpp/language/union

第二个例子向您展示了如何处理非pod联合成员。

应该是这样的

    Foo(bool containsInts) : fooContainsInts(containsInts) 
    {
        if (containsInts) { new (&ints) std::map<std::string, int>;}
        else { new (&strings) std::map<std::string, std::string>;}
    }
    ~Foo()
    {
        if (fooContainsInts) { ints.~map<std::string, int>(); }
        else { strings.~map<std::string, std::string>(); }
    }

我现在不能在MSCV上测试它。

您需要显式地构造和析构非pod联合类型

包括std::map类型在内的大多数STL容器都不能在联合中,因为它具有"非平凡"成员函数。关于什么可以和什么不能在union中存在的更多信息,请参阅wiki。

union用于在多个数据类型之间共享内存。注意,std::map容器将分配存储每个节点实际数据所需的内存。