Segmentation fault inserting in a stl::map

Hi, I need help with something that should be easy (but is not being...).

I'm trying to implement a very classic Factory Method Pattern in C++, I can do it very easily in MS-Visual C++, but in Linux with g++ the code compiles but I get a segmentation fault when I run it. The code is very simple to follow and I reduced it to a very academic code example to try to diagnose the problem. I am building with the C++11 version.

I tested the problem with Netbeans in Ubuntu 14.04 (g++ 4.x and g++5.x), and Codeblocks in Fedora 24 (g++ 6.x) with exactly the same results. Another important information is that when you put all the code in a single compilation unit, it runs well, but that's not what i want, each extension should use its own compilation unit.

Here is the code:

*** File: resourcefactory.h ***
************************************
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef RESOURCEFACTORY_H
#define RESOURCEFACTORY_H

#include <map>
#include <string>
using namespace std;

typedef map<string, string> TMap;

class Resource {
public:
    virtual void get(const TMap& vars) = 0;
    virtual ~Resource() {}
};

typedef map<string, Resource*> TResourceMap;

class Factory
{
public:
    static Resource* getResource(const string& resourcePath);
protected:
    static TResourceMap registry;
};

#endif // RESOURCEFACTORY_H 


*** File: resourcefactory.cpp ***
***************************************
1
2
3
4
5
6
#include <resourcefactory.h>

TResourceMap Factory::registry;
Resource* Factory::getResource(const string& resourcePath) {
    return registry[resourcePath];
}


*** File: brands.h ***
************************************
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef BRANDS_H
#define BRANDS_H

#include <resourcefactory.h>

class Brands : public Resource
{
public:
    void get(const TMap& vars) override;
    virtual ~Brands() {}
};

#endif // BRANDS_H 


*** File: brands.cpp ***
***************************************
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <brands.h>
#include <iostream>
using namespace std;

void Brands::get(const TMap& vars) {
    cout << "I am a BrandsResource\n";
}

class BrandsFactory : public Factory {
    BrandsFactory() {
        static Brands resource;
        registry["/vehicle/brands"] = &resource; // <<== here is the problem!
    }
    static BrandsFactory createThisFactory;
};
BrandsFactory BrandsFactory::createThisFactory;


*** File: main.cpp ***
*************************
1
2
3
4
5
6
7
8
9
10
#include <resourcefactory.h>

int main() {
    // "virtual construction" based on a string value.

    Resource* res = Factory::getResource("/vehicle/brands");
    TMap vars;
    res->get(vars);
    return 0;
}

***********************************

When running, Codeblocks reports me the error in: stl_tree.h
1
2
3
4
5
6
7
8
  ...
      _Self&
      operator--() _GLIBCXX_NOEXCEPT
      {
_M_node = _Rb_tree_decrement(_M_node); // <== here is the error
return *this;
      }
  ...


I am not very good in generic programming, but the error stack dump (as Codeblocks presents it) is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#0 0x7ffff7af60aa??() (/lib64/libstdc++.so.6:??)

#1 0x4028edstd::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> >::operator--(this=0x7fffffffe410) (/usr/include/c++/6.2.1/bits/stl_tree.h:224)

#2 0x40284fstd::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> > >::_M_get_insert_unique_pos(this=0x6062e0 <Factory::registry[abi:cxx11]>, __k="/vehicle/brands") (/usr/include/c++/6.2.1/bits/stl_tree.h:1845)

#3 0x401fffstd::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> > >::_M_get_insert_hint_unique_pos(this=0x6062e0 <Factory::registry[abi:cxx11]>, __position=..., __k="/vehicle/brands") (/usr/include/c++/6.2.1/bits/stl_tree.h:1942)

#4 0x401c6cstd::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> >, std::piecewise_construct_t const&, std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>&&, std::tuple<>&&) (this=0x6062e0 <Factory::registry[abi:cxx11]>, __pos=..., __args#0=..., __args#1=<unknown type in /home/eduardo/cppdev/rentallservices/bin/Debug/rentallservices, CU 0x747d, DIE 0xf2cd>, __args#2=<unknown type in /home/eduardo/cppdev/rentallservices/bin/Debug/rentallservices, CU 0x747d, DIE 0xf8f5>) (/usr/include/c++/6.2.1/bits/stl_tree.h:2200)

#5 0x401aa7std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Resource*, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, Resource*> > >::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) (this=0x6062e0 <Factory::registry[abi:cxx11]>, __k=<unknown type in /home/eduardo/cppdev/rentallservices/bin/Debug/rentallservices, CU 0x747d, DIE 0xf1e5>) (/usr/include/c++/6.2.1/bits/stl_map.h:502)

#6 0x4017b2BrandsFactory::BrandsFactory(this=0x6062c9 <BrandsFactory::createThisFactory>) (/home/eduardo/cppdev/rentallservices/src/brands.cpp:13)

#7 0x401649__static_initialization_and_destruction_0(__initialize_p=1, __priority=65535) (/home/eduardo/cppdev/rentallservices/src/brands.cpp:18)

#8 0x40165f_GLOBAL__sub_I__ZN6Brands3getERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_St4lessIS6_ESaISt4pairIKS6_S6_EEE() (/home/eduardo/cppdev/rentallservices/src/brands.cpp:18)

#9 0x4036fd__libc_csu_init () (??:??)

#10 0x7ffff7189390__libc_start_main() (/lib64/libc.so.6:??)

#11 0x40103a_start () (??:??) 


Any Help?,
Last edited on
Find a possible solution at:

http://stackoverflow.com/questions/27145617/segfault-when-adding-an-element-to-a-stdmap

Will test it and notify the forum.
e.
It worked, avoid static global variables. Use instead static local variables inside a static method.
Topic archived. No new replies allowed.