简体   繁体   中英

Accessing map inside union inside class gives segmentation fault

I am trying to create a class which either contains a map of one type or another, so I decided to use an anonymous union. But my code gives a segmentation fault when I try to access the map (in this case I get a segfault in both the constructor and the destructor):

#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;
}

I would suggest templating the type instead of a union, but maybe this helps you.

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

The second example shows you how to deal with non-POD union members.

It should look like this

    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>(); }
    }

I cant test it on MSCV though right now.

You need to explicitly construct and destruct non-POD union types

Most STL containers including the std::map type cannot be in a union since it has "non-trivial" member functions. See wiki for further information on what can and cannot be inside of a union.

A union is used to share the memory between multiple data types. Note that the std::map container will heap allocate the memory needed to store the actual data for each node. Those heap allocations would not be in the union.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM