Hi, I hope you are fine.

I wish to report a problem with g++ 4.x, g++ 5.x, g++ 6.x. 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. That's why I think is the compiler that is failing.

So, I Wish to contribute to the proyect reporting this issue. Here is the code:

*** File: resourcefactory.h ***
************************************
#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 ***
***************************************
#include <resourcefactory.h>

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

*** File: brands.h ***
************************************
#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 ***
***************************************
#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 ***
*************************
#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
   ...
      _Self&
      operator--() _GLIBCXX_NOEXCEPT
      {
_M_node = _Rb_tree_decrement(_M_node); // <== here is the error
return *this;
      }
   ...

How could I help to fix the problem? I am not very good in generic programming, 
but the error stack dump (as Codeblocks presents it) is:

#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 () (??:??)

Regards,

Eduardo Yánez.

Reply via email to