Search code examples
c++dictionarysegmentation-faultdestructormember-variables

Segmentation fault when a member variable of type std::map is not declared in all compilation units


When I declare a member variable of type std::map in one compilation unit but not the other, I get a segmentation fault when the containing object is being destructed. When I do the same with std::vector, it works just fine.

It was definitely a bug in my case, and I fixed it, but I'm still wondering what's causing the crash.

Here's the code:

foo.hpp:

#ifdef DECLARE_MAP
#include <map>
#endif
#ifdef DECLARE_VECTOR
#include <vector>
#endif
#include <string>

class Foo {
public:
    Foo();

private:
#ifdef DECLARE_MAP
    std::map<std::string, std::string> m;
#endif
#ifdef DECLARE_VECTOR
    std::vector<std::string> v;
#endif
};

foo.cpp:

#include "foo.hpp"

Foo::Foo()
{
}

main.cpp:

#include "foo.hpp"

int main()
{
    Foo f;
}

Works fine with DECLARE_VECTOR:

g++ -DDECLARE_VECTOR -c -o foo.o foo.cpp
g++ -o main main.cpp foo.o

But causes a segmentation fault with DECLARE_MAP:

g++ -DDECLARE_MAP -c -o foo.o foo.cpp
g++ -o main main.cpp foo.o

Reproducible in clang 4.0 and gcc 4.4.7.

Can anybody explain why this happens?


Solution

  • You're violating the One Definition Rule, resulting in Undefined Behaviour. This means literally anything can happen. Which includes working for some types involved and not others, or working only when the moon is full.