segfault when accessing static std::map - c++11

I'm trying to refactor a rather complicated piece of code and run into segfaults during loading the library. This is a minimal example of what I could single out to be the source of the segfault:
#include <iostream>
#include <string>
#include <map>
class Manager {
public:
class Action{
};
static bool registerAction(const Action* a, const char* name);
};
namespace Actions {
class ExampleAction : public Manager::Action {
};
namespace {
static bool available = Manager::registerAction(new ExampleAction(),"ExampleAction");
}
}
namespace {
typedef std::map<const std::string,const Manager::Action*> ActionList;
static ActionList sActions;
}
bool Manager::registerAction(const Action* a, const char* name){
std::cout << "attempting to register action " << a << " as " << name << std::endl;
sActions[name] = a;
std::cout << "done" << std::endl;
return true;
}
int main(){
std::cout << "hello!" << std::endl;
for(auto it:sActions){
std::cout << it.first << std::endl;
}
std::cout << "world!" << std::endl;
return 0;
}
It compiles fine with g++ 4.8.4 using the --std=c++11 flag, but upon execution, this happens:
attempting to register action 0x1ebe010 as ExampleAction
Segmentation fault (core dumped)
The line attempting to register comes first, which is of course expected, but the line assigning the value to the static map instance causes the crash, and I don't understand the reason. I'm probably being stupid here, but still - any suggestions on how to fix this?

Related

Removing segmentation fault and working with destructor c++ [duplicate]

This question already has answers here:
How do I find the length of an array?
(30 answers)
What does sizeof do?
(4 answers)
Closed 10 months ago.
This is student.hpp (Base class)
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <string>
class student
{
public:
student(const std::string& name, const std::string& ssn);
virtual ~student();
virtual void identify();
protected:
// declaring it protected so that i can use it for derived class
std::string studName;
std::string studSSN;
};
student::student(const std::string& name, const std::string& ssn)
: studName(name), studSSN(ssn)
{
std::cout << "Parent Constructor" << std::endl;
}
// destructor for the class
student::~student()
{
std::cout << "Parent Destructor" << std::endl;
}
// displays the information about the student
void student::identify()
{
std::cout << "Name: " << studName << std::endl;
std::cout << "SSN: " << studSSN << std::endl;
}
#endif
This is studentAthlete.hpp (derived class)
#ifndef STUDENTATHLETE_H
#define STUDENTATHLETE_H
#include <iostream>
#include <string>
#include "student.hpp"
class studentAthlete : public student
{
public:
studentAthlete(const std::string& name, const std::string& ssn, const std::string& game);
~studentAthlete();
void identify();
private:
std::string sports;
};
studentAthlete::studentAthlete(const std::string& name, const std::string& ssn, const std::string& game)
: student(name,ssn),sports(game)
{
std::cout << "Child Constructor" << std::endl;
}
studentAthlete::~studentAthlete()
{
std::cout << "Child Destructor" << std::endl;
}
void studentAthlete::identify()
{
student::identify();
std::cout << "Sports: " << sports << std::endl;
std::cout << "Student is an athlete." << std::endl;
}
#endif
This is the main class
#include <iostream>
#include <string>
#include "student.hpp"
#include "studentAthlete.hpp"
int main()
{
student ja("John Anderson", "345-12-3547");
student bw("Bill Williams", "286-72-6194");
studentAthlete bj("Bob Johnson", "294-87-6295", "football");
studentAthlete dr("Dick Robinson", "669-28-9296", "baseball");
// list of student pointers
student* stud[] = {&ja, &bw, &bj, &dr};
int stud_size = (int) sizeof(stud);
for (int i = 0; i < stud_size; i++)
{
stud[i]->identify();
std::cout << std::endl << std::endl;
}
return EXIT_SUCCESS;
}
I tried using the delete function for dislocating pointer or memory leaks.
I don't know how to get rid of the error or to use a destructor.
I am having segmentation fault
zsh: segmentation fault ./"main"
Any help destructor or removing segmentation fault would be appreciated.
Thank you.

copy constructor do not work in cpp template

I'm writing a test program about c++ type erasure, the code is put on the end.
when I run program , the test case 2 output as follow:
A default cstr...0x7ffe0fe5158f
obj_:0x7ffe0fe5158f objaaa 0x7ffe0fe5158f
Print A 0x7ffe0fe5158f
my machine: Linux x86-64, gcc 4.8
In my opinion, "Object obj2(a2);" makes a class Model by lvalue reference, so it should call A's copy constructor,
but actually it did not work, it makes me confused.
someone can give a explanation, thank you in advance.
the program is list as follow:
#include <memory>
#include <iostream>
class Object {
public:
template <typename T>
Object(T&& obj) : object_(std::make_shared<Model<T>>(std::forward<T>(obj))) {
}
void PrintName() {
object_->PrintName();
}
private:
class Concept {
public:
virtual void PrintName() = 0;
};
template <typename T>
class Model : public Concept {
public:
Model(T&& obj) : obj_(std::forward<T>(obj)) {
std::cout << "obj_:" << std::addressof(obj_) <<" objaaa " << std::addressof(obj) << std::endl;
}
void PrintName() {
obj_.PrintName();
}
private:
T obj_;
};
private:
std::shared_ptr<Concept> object_;
};
class A {
public:
A(A& a) {
std::cout<< "A copy cstr...a" << this << std::endl;
}
A(A&& a) {
std::cout << "A move cstr...." <<this<< std::endl;
}
A() {
std::cout << "A default cstr..." <<this<< std::endl;
}
void PrintName() {
std::cout << "Print A " << this << std::endl;
}
};
int main(void)
{
// test case 1
Object obj{A()};
obj.PrintName();
// test case 2
A a2;
Object obj2(a2);
obj2.PrintName();
return 0;
}
In Object obj2(a2);, no copy is made. T in the constructor of Object is deduced to be A&, so it instantiates Model<A&>, which stores a reference to the original a2 object as its obj_ member.
Observe that in your debug output, a2's constructor, Model's constructor and PrintName all print the same address. You can further confirm that this address is in fact &a2.

How to work out types required for std::for_each lambda function

I am confused about how to work out what type is required to use a lambda function in std::for_each. It seems I cannot use auto in this case as a parameter (Visual Studio 2013 complains anyway).
In the code below I would have thought I would use sections as the type for the for_each function, but in fact I have to use
const std::pair<std::string, std::unordered_map<std::string, std::string> >
And for the 'inner' type in this case what do I use?
My main question is how I work out what type to use?
#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>
// key=value pairs within a section
typedef std::unordered_map<std::string, std::string> keyvalue;
// [section1] - top level
typedef std::unordered_map< std::string, std::unordered_map<std::string, std::string> > sections;
class config
{
public:
config() {
setup();
}
typedef sections::iterator iterator;
iterator begin() { return sections_.begin(); }
iterator end() { return sections_.end(); }
private:
sections sections_;
void setup() {
// obviously we wouldn't hard code like this in a real program
sections_["programming languages"].insert(std::make_pair("C", "imperative"));
sections_["programming languages"].insert(std::make_pair("C++", "OOP"));
sections_["programming languages"].insert(std::make_pair("Java", "OOP"));
sections_["programming languages"].insert(std::make_pair("Haskell", "functional"));
sections_["programming languages"].insert(std::make_pair("Prolog", "logic"));
}
};
int main() {
config cfg;
std::for_each(cfg.begin(), cfg.end(), [](const std::pair<std::string, std::unordered_map<std::string, std::string> > sec) {
std::cout << "section name: " << sec.first << std::endl;
// what is inner type - thought it would be keyvalue ???
//std::for_each(sec.second.begin(), sec.second.end(), [](const keyvalue& pr) {
//std::cout << "first: " << pr << std::endl;
//});
});
// I thought type would be sections ???
//std::for_each(cfg.begin(), cfg.end(), [](const sections& sec) {
// std::cout << "section name: " << sec.first << std::endl;
//});
}
You can also use decltype for this purpose like this:
config cfg;
std::for_each(cfg.begin(), cfg.end(), [](const decltype(*cfg.begin())& sec) {
std::cout << "section name: " << sec.first << std::endl;
std::for_each(sec.second.begin(), sec.second.end(), [](const decltype(*sec.second.begin())& pr) {
std::cout << "first: " << pr.first << std::endl;
});
});
I'm not 100% certain how reference types affect this, so removing it might be more appropriate like const std::remove_reference<decltype(*cfg.begin())>::type& sec
Although it should be noted that VS2013 ItelliSense has trouble with decltype and will mark it as an error even if it compiles fine.
STL containers always define a value_type so in that case you can use decltype(inst)::value_type and you don't need the remove_reference shenanigans. So I would advise you to also add a value_type typedef to your type like this:
class config
{
public:
typedef sections::value_type value_type;
Then you can do:
config cfg;
std::for_each(cfg.begin(), cfg.end(), [](const decltype(cfg)::value_type& sec) {
std::cout << "section name: " << sec.first << std::endl;
std::for_each(sec.second.begin(), sec.second.end(), [](const decltype(sec.second)::value_type& pr) {
std::cout << "first: " << pr.first << std::endl;
});
});

I'm using :: operator but I still get error that enum class error is not a class, namespace, or scoped enum

I want to print my Car object's color and noise. I'm trying to use c++11's enum class within my Car class. When I compile I get error Car::Color and Car::Noise is not a class, namespace, or scoped enumeration. I am using the :: operator to access the enum class. But the error persists. The problem seems to lie in the Car.cpp file. Here is my code. Any advice is much appreciated. Thanks so much.
Car.h
class Car {
public:
enum class Color {red, yellow, blue};
enum class Noise {loud, soft, medium};
void setColor();
void setNoise();
void getColor();
void getNoise ();
private:
Color c;
Noise n;
};
Car.cpp
#include<iostream>
#include "Car.h"
using namespace std;
void Car::setColor() {
c = Color::red;
}
void Car::setNoise() {
n = Noise::loud;
}
void Car::getColor() {
switch(c) {
case Color::red: cout << "red" << endl;
case Color::yellow: cout << "yellow" << endl;
case Color::blue: cout << "blue" << endl;
default:
cout << "error" << endl;
}
}
void Car::getNoise() {
switch(n) {
case Noise::loud: cout << "loud" << endl;
case Noise::soft: cout << "soft" << endl;
case Noise::medium: cout << "medium" << endl;
default: cout << "error" << endl;
}
}
main.cpp
#include <iostream>
#include "Car.h"
int main() {
Car car;
car.setColor();
car.setNoise();
car.getColor();
car.getNoise();
}
My compiler was outdated. All's working now.

Mac OS X : boost interprocess semaphore timed_wait : Abnormal CPU consumption

After porting a code segment from Windows to Mac OS X, I found it to consume a whole CPU core while running; the responsible call for the CPU consumption is boost::interprocess::interprocess_semaphore::timed_wait.
Here follows the code portion which reproduces this behaviour.
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/thread/thread_time.hpp>
#include <iostream>
static bool gStopRequested(false);
struct ShmObj
{
boost::interprocess::interprocess_semaphore mSemaphore;
ShmObj() : mSemaphore(0) {};
~ShmObj() {};
};
int main(char* argc, const char** argv)
{
boost::interprocess::shared_memory_object* lShmObj = NULL;
std::string lShmObjName("My_Boost_Interprocess_Test");
boost::interprocess::mapped_region* lRegion;
ShmObj* lObj;
//Create shared segment
try
{
lShmObj = new boost::interprocess::shared_memory_object(boost::interprocess::create_only, lShmObjName.c_str(), boost::interprocess::read_write);
}
catch (boost::interprocess::interprocess_exception &ex)
{
if (ex.get_error_code() != boost::interprocess::already_exists_error)
{
std::cerr << "Some error" << std::endl;
exit(1);
}
else
{
std::cerr << "Already exists, just taking it back." << std::endl;
try
{
lShmObj = new boost::interprocess::shared_memory_object(boost::interprocess::open_only, lShmObjName.c_str(), boost::interprocess::read_write);
}
catch (boost::interprocess::interprocess_exception &ex2)
{
std::cerr << "D'oh !" << std::endl;
exit(1);
}
}
}
if (!lShmObj)
{
exit(1);
}
lShmObj->truncate(sizeof(ShmObj));
lRegion = new boost::interprocess::mapped_region(*lShmObj, boost::interprocess::read_write);
lObj = new (lRegion->get_address()) ShmObj;
// The loop
while (!gStopRequested)
{
boost::system_time lDeadlineAbsoluteTime = boost::get_system_time() + boost::posix_time::milliseconds(500);
if (lObj->mSemaphore.timed_wait(lDeadlineAbsoluteTime))
{
std::cout << "acquired !" << std::endl;
}
else
{
std::cout << "tick" << std::endl;
}
}
}
Then, I read that unnamed semaphores were not available under Mac OS X, so I thought it could be because unnamed semaphores were not efficiently emulated... I then tried the following, unsucessfully:
#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread/thread_time.hpp>
#include <iostream>
static bool gStopRequested(false);
int main(char* argc, const char** argv)
{
boost::interprocess::named_semaphore::remove("My_Boost_Interprocess_Test");
boost::interprocess::named_semaphore lMySemaphore(boost::interprocess::open_or_create, "My_Boost_Interprocess_Test", 1);
// The loop
while (!gStopRequested)
{
boost::system_time lDeadlineAbsoluteTime = boost::get_system_time() + boost::posix_time::milliseconds(500);
if (lMySemaphore.timed_wait(lDeadlineAbsoluteTime))
{
std::cout << "acquired !" << std::endl;
}
else
{
std::cout << "tick" << std::endl;
}
}
}
I was actually expecting a better behaviour of boost::interprocess on Mac OS X because of the available Posix primitives, but it is actually not. Any idea for a resolution? Thanks a lot.
I successfully Used Mach semaphores instead of the ones of boost::interprocess... see http://pkaudio.blogspot.com/2010/05/mac-os-x-no-timed-semaphore-waits.html

Resources