C++: std::map<int,int> crashes when being assigned - c++

I'm trying to make an int to int map but the program crashes and I don't realize why.
I've summarized the problem to this short simple code.
When the program starts, since the Utilities member _instance is static- it initialize it, by going to its constructor, which contain a single line: An int to int (simple) map assignment. but then it crashes.
Notice that if I comment that line, the program doesn't crash,
and that the main contains that very same line.
So my two questions are:
1) Why does it crash? is there a point behind this behavior?
2) How do I fix it so I can initialize the map at constructor?
Thank You
#include <map>
class Utilities
{
public:
~Utilities(){};
static Utilities& instance();
private:
Utilities();
Utilities( const Utilities& ){};
static Utilities _instance;
static std::map<int, int> textIntToIntMap;
};
Utilities Utilities::_instance = Utilities();
std::map<int, int> Utilities::textIntToIntMap;
Utilities::Utilities()
{
//The following line crashes, why?
textIntToIntMap[1] = 2;
}
int main()
{
static std::map<int, int> text2;
text2[4] = 2;
int xxx = 3;
}

You have an initialization order problem:
Utilities Utilities::_instance = Utilities();
This line calls the default constructor of Utilities, which then tries to populate the map. But the map is not initialized at this stage.
You should design your code to be robust against such initialization order issues. You can mitigate some of that by creating static instances inside functions. This gives you a handle on the ordering of initializations. But a simple re-ordering of the definitions should fix the immediate problem:
std::map<int, int> Utilities::textIntToIntMap;
Utilities Utilities::_instance = Utilities(); // OK, map has been defined

The issue is that you call the Utilities constructor before Utilities::textIntToIntMap has been constructed.
Swap the order of the following two lines:
Utilities Utilities::_instance = Utilities();
std::map<int, int> Utilities::textIntToIntMap;

Before initializing _instance you need to define map textIntToIntMap outside the class. Because in constructor you are using textIntToIntMap which is a static member so you need to define it first. So outside the class use following lines:
std::map<int, int> Utilities::textIntToIntMap;
Utilities Utilities::_instance = Utilities();

Others have already caught that the Utilities() are constructed before Utilities::textToIntMap. So, now the question is: how to avoid such problems in the future?
You can use a function returning a reference to a static local variable to ensure that the construction is done before the reference is used. You can put such function into a namespace. You should also have a convenience typedef with hopefully a shorter name, so that declaring iterators is not a finger-breaker on C++98. On C++11 you should be using auto anyway.
Note that the use of global or function-static non-POD data is not thread-safe in C++98. If you wish to safely use textToMap() from multiple threads, with no guarantee that it was accessed before the 2nd thread was started, textToIntMap would need to wrap the initialization within a mutex. To get a rough idea how this might be done, see the inner function from Qt's convenient Q_GLOBAL_STATIC.
The use of a singleton class seems like a pointless Java-ism in this case.
Run a test on ideone.
// Utilities.h
namespace Utilities {
typedef std::map<int, int> Map;
Map & textToIntMap();
}
// Utilities.cpp
namespace Utilities {
namespace {
struct InitializedMap : Map {
InitializedMap() {
insert(value_type(1, 2));
// or
(*this)[1] = 2;
}
};
}
Map & textToIntMap() {
static InitializedMap map;
return map;
}
}

Try this way::
#include <map>
#include <iostream>
using namespace std;
class Utilities
{
public:
static Utilities& instance() {
static Utilities instance;
return instance;
}
~Utilities(){};
void PrintMapValues();
void AddKeyValue(int key, int value);
private:
Utilities();
Utilities( const Utilities& ){};
std::map<int, int> int_to_int_map_;
};
Utilities::Utilities()
{
//The following line crashes, why?
int_to_int_map_[-99] = 2;
}
void Utilities::PrintMapValues() {
for(std::map<int, int>::iterator it = int_to_int_map_.begin(); it != int_to_int_map_.end(); ++it){
cout << "Key:" << it->first << " Val:" << it->second << endl;
}
}
void Utilities::AddKeyValue(int key, int value) {
int_to_int_map_[key] = value;
}
int main()
{
Utilities& utils = Utilities::instance();
for (int i=0; i< 10; i++) {
utils.AddKeyValue(i, i+20);
}
utils.PrintMapValues();
return 0;
}

Related

Insert an object pointer into a map of maps through emplace() does not work

I'm trying to insert a pointer object to a map through emplace() but it does not work.
I've created a simple representation of the problem below. I'm trying to insert to newFooList pointer object type Foo*.
I can't seem to find a way to create a type for FooMap* in std::map<int, FooMap*> m_fooMapList. Should it be done with the new on the second field of the map?
#include <iostream>
#include <utility>
#include <stdint.h>
#include <cstdlib>
#include <map>
class Foo
{
private:
int m_foobar;
public:
Foo(int value)
{
m_foobar = value;
}
void setfoobar(int value);
int getfoobar();
};
class FooMap
{
private:
std::map<int, Foo*> m_newFoo;
public:
FooMap() = default;
};
class FooMapList
{
private:
std::map<int, FooMap*> m_fooMapList;
public:
FooMapList() = default;
void insertFoo(Foo* newFooObj);
};
int Foo::getfoobar(void)
{
return(m_foobar);
}
void FooMapList::insertFoo(Foo* newFooObj)
{
if(m_fooMapList.empty())
{
std::cout << "m_fooMapList is empty" << std::endl ;
}
//m_fooMapList.emplace( newFooObj->getfoobar(), newFooObj );
// Need to find a way to insert newFooObj to m_fooMapList
m_fooMapList.second = new FooMap;
}
int main() {
FooMapList newFooList;
for (auto i=1; i<=5; i++)
{
Foo *newFoo = new Foo(i);
newFoo->getfoobar();
newFooList.insertFoo(newFoo);
}
return 0;
}
On g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)
$ g++ -std=c++11 -Wall map_of_map.cpp
map_of_map.cpp: In member function ‘void FooMapList::insertFoo(Foo*)’:
map_of_map.cpp:51:18: error: ‘class std::map<int, FooMap*>’ has no member named ‘second’
m_fooMapList.second = new FooMap;
m_fooMapList is defined as
std::map<int, FooMap*> m_fooMapList;
So to insert into it, you need an int and a pointer to FooMap:
m_fooMapList.emplace(newFooObj->getfoobar(), new FooMap);
Having said that, you should use C++ value semantics and rely less on raw pointers:
std::map<int, FooMap> m_fooMapList; // no pointers
m_fooMapList.emplace(newFooObj->getfoobar(), {}); // construct objects in-place
That is, instances of FooMap can reside directly in the map itself.
That way you get better performance and avoid memory leaks.
It's also worth looking into smart pointers (e.g. unique_ptr) if you really want to work with pointers.
I am not sure if you need a map structure where the values are pointers to another map. The FooMapList class could be simple
std::map<int, FooMap> m_fooMapList;
On the other hand, the entire play with the row pointer will bring you nothing but a pain on the neck.
In case the use of
std::map<int, FooMap*> m_fooMapList; and std::map<int, Foo*> are neccesarry, I would go for smartpointers.
Following is an example code with replacing row pointers with std::unique_ptr and shows how to insert map of Foo s to map in-place. See live here
#include <iostream>
#include <utility>
#include <map>
#include <memory>
class Foo
{
private:
int m_foobar;
public:
Foo(int value): m_foobar(value) {}
void setfoobar(int value) noexcept { m_foobar = value; }
int getfoobar() const noexcept { return m_foobar; }
};
class FooMap
{
private:
std::map<int, std::unique_ptr<Foo>> m_newFoo;
// ^^^^^^^^^^^^^^^^^^^^
public:
FooMap() = default;
#if 0 // optional
// copy disabled
FooMap(const FooMap&) = delete;
FooMap& operator=(const FooMap&) = delete;
// move enabled
FooMap(FooMap&&) = default;
FooMap& operator=(FooMap&&) = default;
#endif
// provide a helper function to insert new Foo to the map of Foo s
void insertFoo(std::unique_ptr<Foo> newFooObj)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
std::cout << "inserting to FooMap..." << std::endl;
m_newFoo.emplace(newFooObj->getfoobar(), std::move(newFooObj)); // construct in place
}
};
class FooMapList
{
private:
std::map<int, std::unique_ptr<FooMap>> m_fooMapList;
// ^^^^^^^^^^^^^^^^^^^^^^^
public:
FooMapList() = default;
void insertFooMap(std::unique_ptr<Foo> newFooObj)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
if (m_fooMapList.empty())
{
std::cout << "m_fooMapList is empty" << std::endl;
}
// create FooMap and insert Foo to it.
FooMap fooMap;
const auto key = newFooObj->getfoobar();
fooMap.insertFoo(std::move(newFooObj));
// finally insert the FooMap to m_fooMapList
std::cout << "inserting to fooMapList..." << std::endl;
m_fooMapList.emplace(key, std::make_unique<FooMap>(std::move(fooMap))); // construct in place
}
};
int main()
{
FooMapList newFooList;
for (auto i = 1; i <= 5; i++)
{
auto newFoo = std::make_unique<Foo>(i);
std::cout << newFoo->getfoobar() << std::endl;
newFooList.insertFooMap(std::move(newFoo));
}
return 0;
}
Output:
1
m_fooMapList is empty
inserting to FooMap...
inserting to fooMapList...
2
inserting to FooMap...
inserting to fooMapList...
3
inserting to FooMap...
inserting to fooMapList...
4
inserting to FooMap...
inserting to fooMapList...
5
inserting to FooMap...
inserting to fooMapList...
You can throw away your do-nothing map classes, stop using pointers, and just
#include <iostream>
#include <utility>
#include <stdint.h>
#include <cstdlib>
#include <map>
class Foo
{
private:
int m_foobar;
public:
Foo(int value) : m_foobar(value) { }
void setfoobar(int value) { m_foobar = value; }
int getfoobar() const { return m_foobar; }
// or more simply
// int foobar;
};
using FooMap = std::map<int, Foo>;
using FooMapMap = std::map<int, FooMap>;
int main() {
FooMapMap foos;
for (auto i=1; i<=5; i++)
{
foos[i][i] = Foo(i);
}
return 0;
}
Do note that the inner map is totally pointless at this stage, as they only ever have one entry
Except if you have a really good reason to do so, avoid to obfuscate things a la Java like this and try to leverage the STL anyway you can. To that end you can use type aliases
using FooMap = std::map<int, Foo*>; // Maybe use a smart pointer instead here?
using FooMapList = std::map<int, FooMap>; // Maybe List is not an appropriate name for a map
Now, you have a Foo element you just created and want to insert it in your map list, to do so you need a way to select in which map in the list you want to insert it. I will assume you'll insert in the first map in the list:
auto FooMap::emplace(int key, Foo* value)
{
return m_newFoo.emplace(key, value);
}
void FooMapList::insertFoo(Foo* newFooObj)
{
// If the map for `getfoobar` does not exist yet, operator[] will create it
auto& mapPtr = m_fooMapList[newFooObj->getfoobar()];
if (nullptr == mapPtr)
mapPtr = new FooMap();
mapPtr->emplace(
newFooObj->getfoobar(),
newFooObj
);
}
Note that I didn't handle memory cleanup. I suggest you try to use smart pointers when applicable (std::unique_ptr and std::shared_ptr)
I have considered valid points from each of the answers to remove pointers and remove useless double level map representations. But the real world abstraction is a much complex problem which involves thousands of objects on the fly which needs to be created and destroyed dynamically. Using pointers seemed a valid approach, but JeJo' approach seemed much better.
I tried to re-use his attempt but with object pointers and the below seems to work. With the below insert functions
In the FooMap class the function would be
void FooMap::insertFoo(Foo* newFooObj)
{
m_newFoo.emplace(newFooObj->getfoobar(), newFooObj);
}
const std::map<int, Foo*> FooMap::getList()
{
return m_newFoo;
}
and in FooMapList it would be
void FooMapList::insertFooList(Foo* newFooObj)
{
std::map <int, FooMap*>::iterator iter;
FooMap *localFooMap = NULL;
iter = m_fooMapList.find( newFooObj->getfoobar() );
if( iter == m_fooMapList.end() )
{
localFooMap = new FooMap;
localFooMap->insertFoo(newFooObj);
m_fooMapList.emplace(newFooObj->getfoobar(), localFooMap );
}
else
{
localFooMap = iter->second;
localFooMap->insertFoo(newFooObj);
m_fooMapList.emplace(newFooObj->getfoobar(), localFooMap );
}
}
const std::map<int, FooMap*> FooMapList::getList()
{
return m_fooMapList;
}
I would appreciate feedback for this approach too. I will be adding the calls to destructor to clean up the created objects

Non-const variable initialization before constant objects of class are created

I have a vector:
std::vector<uint16_t> free_ids;
I need for it operator== of my class GameObject. When an object is created, it will receive free id from vector, thus it will be "moved" from it to object. It will get values simply like this:
void init(void)
{
for(uint64_t i=0; i<30; ++i)
free_ids.push_back(i);
}
So I have class that uses that succesfully.
class GameObject
{
public:
static std::vector<GameObject*> created_objects; // all objects created ever
static constexpr auto& CO = created_objects;
GameObject()
{
id = free_ids.front(); // get id from vector
free_ids.erase(free_ids.begin()); // delete it from vector
CO.push_back(this); // add address to all object created ever
}
GameObject(const GameObject& other)
{
// copy attributes I didn't include in this code
id = free_ids.front();
free_ids.erase(free_ids.begin());
CO.push_back(this);
}
~GameObject()
{
free_ids.push_back(id); // return id to vector
CO.erase(std::remove(CO.begin(), CO.end(), this), CO.end());
// remove object by address
}
bool operator==(const GameObject& other)
{
return id==other.id; // check if id is the same (if it's the same object)
}
const uint64_t& get_id(void) const
{
return id;
}
private:
uint64_t id;
};
std::vector<GameObject*> GameObject::created_objects;
I'd love to have global constant of type GameObject, but it will cause segmentation fault, because init() was never called before main() call
//const GameObject Progenitor; //segmentation fault, free_ids not initialized yet
And a sample program:
int main()
{
srand(time(NULL));
init();
const GameObject Progenitor; // It's temporary replacement for my global
std::vector<GameObject> clone_army;
clone_army.reserve(20); // GameObjects can't be reallocated bacause
// their addresses are stored in class static vector
auto& CA = clone_army;
for(uint64_t i=0; i<20; ++i)
CA.push_back(Progenitor);
std::cout << "Storage used. Unoccupied ids: " << std::endl;
for(auto& x : free_ids)
std::cout << x << std::endl;
auto& victim = clone_army[rand()%20]; // it's much more compilated
std::cout << "\nOne will die. Victim is... clone no. " << victim.get_id() << std::endl;
CA.erase(std::remove(CA.begin(), CA.end(), victim), CA.end());
// need to remove victim by value, operator== involved
std::cout << "\nProgenitor id: ";
for(auto& x : GameObject::CO)
std::cout << x->get_id() << std::endl;
}
Responsible headers:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
My question is, how to initialize std::vector<uint16_t> free_ids; - which can't be const, before any object of GameObject class is ever created?
(There will be many progenitors of different inherited classes, template-like objects that I will use (already am but want to rearrange code) to create real-time clones)
While it is easy to create a static object which will initialize the vector in it's constructor, you can never guarantee that this static object will be initialized before all other static objects in different translation units.
Instead, what you might do is to employ a singleton-type thing. Within this singleton, you can expose get_id and release_id functions. Judging by the code provided, I do not think you need me to sketch out this singleton for you, but if you do, feel free to request.
To be honest, you could just do this.
class GameObject
{
private:
using InstanceId = unsigned long long;
static InstanceId _OBJECT_ID = 0;
protected:
const InstanceId mId;
public:
GameObject()
: mId(_OBJECT_ID++)
{}
};
Of course you could get conflicts if your game spawns more than 18446744073709551615 objects during a run.
Easy option:
You could define a helper class, that make sure that your vecotr is initialized only once:
class GameObjectHelper {
static bool done;
public:
GameObjectHelper() {
if (!done) {
init();
done = false;
}
}
};
bool GameObjectHelper::done = false;
Then you can make sure that the constructor of this object is called before the constructor of GameObject by taking benefit of the fact that a base class is constructed before its derived:
class GameObject : private GameObjectHelper {
...
} ;
Important edit: If your GameObjects are multithreaded, done will be initialized to false only once in a thread safe fashion. Unfortunately, several threads could enter the if statement and lead to a race condition. I didn't address this topic in first place, because your remaining code doesn't show evidence of multithreading: your access to the global vector is not thread safe and might lead to adverse race conditions. If you really need multithreading, and if you can't apply the second option, then you should use atomic done with compare_exchange_strong() to test its value.
Cleaner variant:
If you want to avoid your vector being global, you could as well define a helper class such as:
class GameObjectHelper {
vector<uint16_t> free_ids;
public:
GameObjectHelper() {
for(uint64_t i=0; i<30; ++i)
free_ids.push_back(i);
}
}
};
and create a static member obect in the GameObject class:
class GameObject {
protected:
static GameObjectHelper goh;
...
} ;
Of course this works if and only if your vector is solely used by GameObject and its derivates.
But this one is threadsafe, as there the static object is guaranteed to be initialized only once.

How to make a static map in c++?

I am working on 2 files, lets take file1.cpp and file2.cpp.
file1.cpp contains:
//File 1
#include <iostream>
#include <map>
struct category {
int id;
};
void fun();
std::map<char, category> mymap1;
static std::map<char, category> mymap;
std::map<char, category>::iterator map_iter;
std::map<char, category>::iterator map_iter1;
int main ()
{
mymap1['a'] = {20};
mymap1['b'] = {30};
mymap1['c'] = {40};
for(int i = 0;i < 4; i++)
fun();
return 0;
}
//File 2
#include<file2.h>
void fun()
{
mymap = mymap1;
map_iter = mymap.begin();
for (map_iter1 = mymap1.begin(); map_iter1 != mymap1.end();++map_iter1)
{
map_iter->second.id = map_iter1->second.id - map_iter->second.id;
std::cout<<map_iter1->second.id<<" " <<map_iter->second.id;
map_iter->second.id=map_iter1->second.id;
++map_iter;
}
}
I am trying to initialize mymap once when for loop run for the first time after that initialization should not happen as it happen in static variable.
But this behaviour is not shown and each time mymap is getting initialize.
I don't want the "id" getting initialize every time.
How to work?
Create a function that returns a static map
static std::map<char, category> maps() {
static std::map<char, category> m;
//...
return m;
}
If I understand your question correctly, you should be checking before assigning anything to mymap in your fun() function if you only want to initialize it once.
For example, you could pass a variable by reference in your function by adding a parameter, let's call it foo. You initialize it to 0 before your for loop, add a check in your function to make sure that foo == 0 and increment it at the end.
in general 'initialize once' is done like:
void foo()
{
static bool first = true;
if( first )
{
first = false;
// first time init here
}
// rest of func here
}
Also a note on what static means:
static on a global variable:
* only accessible in local translation unit
static on a function:
* only accessible in local translation unit
static on a local variable:
* persists through calls, only one instance even on multiple/recursive call
static on a class/struct member:
* only one instance, regardless of number of parent objects

C++ Assign a const value at run-time?

I have a constant value that never changes during run-time, but is impossible to know until run-time.
Is there a way to declare a constant (either as a member of a class or not) without defining it and also assign a computed value once (and only once) it is determined; or am I going to have to resort to a non-const declaration and use coding S & Ps (ALL_CAPS variables names, static declaration if in a class, etc.) to try and keep it from changing?
CLARIFICATION:
Though these are good answers, the real-world situation I have is more complicated:
The program has a main loop that continually runs between processing and rendering; the user can set required options and once they are set they will never change until the program is restart. An "Initialize" function is set up for anything that can be determined before the main loop, but values that are dependent on user interaction must be performed in the middle of the loop during the processing phase. (At the moment, persistent data storage techniques come to mind...)
Something like this?
const int x = calcConstant();
If it's a class member, then use the constructor initialisation list, as in Yuushi's answer.
You can define it in a struct or class and utilize an initialisation list:
#include <iostream>
struct has_const_member
{
const int x;
has_const_member(int x_)
: x(x_)
{ }
};
int main()
{
int foo = 0;
std::cin >> foo;
has_const_member h(foo);
std::cout << h.x << "\n";
return 0;
}
As a static or function-local variable:
const int x = calcConstant();
As a class member:
struct ConstContainer {
ConstContainer(int x) : x(x) {}
const int x;
};
Yes, you can make a private static singleton field with an initialization method and a gettor method. Here's an example of how to do it:
// In foo.h
class Foo
{
public:
// Caller must ensure that initializeGlobalValue
// was already called.
static int getGlobalValue() {
if (!initialized) {
... handle the error ...
}
return global_value;
}
static void initializeGlobalValue(...)
private:
static bool initialized;
static int global_value;
};
// In foo.cpp
bool Foo::initialized = false;
int Foo::global_value;
void Foo::initializeGlobalValue(...) {
if (initialized) {
...handle the error...
}
global_value = ...;
initialized = true;
}

C++ -- how to initialize the static variable inside a member function?

void ClassA::Func()
{
static map<int, string> mapIntStr;
mapIntStr[0] = m_memberVariable0; <= just want to do once & m_memberVariable* are not static
mapIntStr[1] = m_memberVariable1; <= just want to do once
...
}
I want to ONLY initialize the variable mapIntStr once. As we know, we can put the initialize code inside a static function and call that static function and store the return value into mapIntStr.
Here I would like to get a quick & dirty solution. As I remember, there is something called static scope. I would like to initialize mapIntStr ONCE without calling a static function. how can I do it?
Thank you
void ClassA::Func()
{
static map<int, string> mapIntStr;
if(mapIntStr.empty()){
mapIntStr[0] = m_memberVariable0;
mapIntStr[1] = m_memberVariable1;
// ...
}
}
How about that? :)
Edit
Well, the best solution would be to take the mapIntStr out of the function and into the class. And then you won't get around the static function call.
//in ClassA.h
class ClassA{
public:
void Func();
static map<int,string> InitStatic();
static map<int,string> mapIntStr;
};
//in ClassA.cpp
#include "ClassA.h"
void ClassA::Func(){
// use mapIntStr
}
map<int,string> ClassA::InitStatic(){
map<int,string> ret;
// init ret
return ret;
}
map<int,string> ClassA::mapIntStr = ClassA::InitStatic();
That're about the only options that I know of. So you've got the choice. Initialize the map once in the func or even in a contructor the first time a ClassA object is created (better version of the two) and live with the overhead of a nearly noop call to empty(), which will most likely be a single instruction only after proper inlining and will impose no overhead whatsoever, or use a static initialization function.
Create a inside struct, then initialize everything in the constructor of that struct, and then you declare a static variable of that struct.
void fun()
{
struct setter
{
setter(){}
};
static setter setup;
}
For your case:
void ClassA::Func()
{
struct Map : public std::map<int, string>
{
Map()
{
(*this)[0] = something;
(*this)[1] = somethingElse;
}
}
static Map map;
}