在 class 内访问 union 内的地图会出现分段错误
Accessing map inside union inside class gives segmentation fault
我正在尝试创建一个 class,其中包含一种或另一种类型的地图,因此我决定使用匿名联合。但是当我尝试访问地图时,我的代码给出了一个段错误(在这种情况下,我在构造函数和析构函数中都遇到了段错误):
#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 容器不能在联合中,因为它具有 "non-trivial" 成员函数。请参阅 wiki 了解关于什么可以和不可以在联合中的更多信息。
联合用于在多种数据类型之间共享内存。请注意,std::map
容器将为每个节点 heap 分配存储实际数据所需的内存。那些堆分配不会在联合中。
我正在尝试创建一个 class,其中包含一种或另一种类型的地图,因此我决定使用匿名联合。但是当我尝试访问地图时,我的代码给出了一个段错误(在这种情况下,我在构造函数和析构函数中都遇到了段错误):
#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 容器不能在联合中,因为它具有 "non-trivial" 成员函数。请参阅 wiki 了解关于什么可以和不可以在联合中的更多信息。
联合用于在多种数据类型之间共享内存。请注意,std::map
容器将为每个节点 heap 分配存储实际数据所需的内存。那些堆分配不会在联合中。