std::map inizialitazion (only one time) - c++

I have a function that translates data using std::map
struct HistoParameter
{
int nbins;
float first;
float last;
HistoParameter(int _nbins, int _first, int _last) :
nbins(_nbins), first(_first), last(_last) {};
};
HistoParameter* variable_to_parameter(char* var_name)
{
std::map<const std::string, HistoParameter*> hp;
hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
hp[std::string("ph_eta")] = new HistoParameter(100,-3,3);
// ...
return hp[var_name];
}
My struct is very light, but image it can be heavy. The prolem is that every time I call this function it create a lot of HistoParameter objects, maybe a switch case is more efficient. First question: I'm creating garbage?
Second solution:
bool first_time = true;
HistoParameter* variable_to_parameter(char* var_name)
{
static std::map<const std::string, HistoParameter*> hp;
if (first_time)
{
hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
hp[std::string("ph_eta")] = new HistoParameter(100,-3,3);
// ...
}
first_time = false;
return hp[var_name];
is it ok? Better solution?

The second solution seems OK to me - you can say:
if ( hp.empty() ) {
// populate map
}
I would also consider making it a map of values rather than pointers - I don't see you need dynamic allocation here:
std::map <std::string, HistoParameter> hp;
then:
hp["ph_pt"] = HistoParameter(100,0,22000);
Note you don't need the explicit std::string conversion. Or better still:
hp.insert( std::make_pair( "ph_pt", HistoParameter(100,0,22000 )));

The first solution produces a lot of garbage. Why don't you return the class by value? It's quite lightweight, and you wouln't have to dynamically allocate it.
HistoParameter variable_to_parameter(char* var_name)
{
static std::map<const std::string, HistoParameter> hp;
if ( hp.empty() )
{
hp.insert( std::make_pair( "ph_pt", HistoParameter(100,0,22000) ) );
hp.insert( std::make_pair( "ph_eta", HistoParameter(100,-3,3) ) );
//...
}
return hp[var_name];
}
If the class returned gets larger, and you want a power-tool, then try out boost::flyweight.
If you don't want to pass back a big structure, you can do:
HistoParameter& variable_to_parameter(char* var_name)
{
// same code
}
... and even throw in a const if you want it immutable.
Edit: added make_pair, as suggested by Niel.

Your second solution should certainly improve efficiency, but isn't (at least IMO) the best implementation possible. First of all, it makes first_time publicly visible, even though only variable_to_parameter actually cares about it. You've already made hp a static variable in the function, and first_time should be as well.
Second, I would not use pointers and/or dynamic allocation for the HistoParameter values. At one int and two floats, there's simply no reason to do so. If you're really passing them around so much that copying became a problem, you'd probably be better off using some sort of smart pointer class instead of a raw pointer -- the latter is more difficult to use and much more difficult to make exception safe.
Third, I'd consider whether it's worthwhile to make variable_to_parameter into a functor instead of a function. In this case, you'd initialize the map in the ctor, so you wouldn't have to check whether it was initialized every time operator() was invoked. You can also combine the two, by have a static map in the functor. The ctor initializes it if it doesn't exist, and operator() just does a lookup.
Finally, I'd note that map::operator[] is primarily useful for inserting items -- it creates an item with the specified key if it doesn't exist, but when you're looking for an item, you usually don't want to create an item. For this, you're generally better off using map.find() instead.

I'd have a std::map< std::string, HistoParameter *> member and do
InitializeHistoParameter()
{
myMap["ph_pt"] = new ...
myMap["ph_eta"] = new ...
}
And then
HistoParameter* variable_to_parameter(char* var_name)
{
return myMap[var_name];
}

either way, you are creating memory leak.
each time the = operator is called, for example:
hp[std::string("ph_pt")] = new HistoParameter(100,0,22000);
you are creating a new HistoParameter object and pairing the key "ph" with this most recent object, leaving the previous one dangling.
If creating a new object each time is your actual intent, you probably need to call
delete hp[std::string("ph_pt")];
before the new operation.
My suggestion is to avoid raw new operations as much as possible and resort to smart pointers such as boost::share_ptr for object life time management.

Related

C++ What syntax for avoid duplicated declarations?

I'm learning C++ and especially OO Programming.
My program use pointers to deal with Dynamic memory allocation.
While creating my default constructor, I was boring about repeat myself with
myInt = new int;
myOtherInt = new int;
etc..
So my question is : is there a way to write something like :
myInt, myOtherInt = new int;
Here's my constructor code :
Annonce::Annonce(string Titre, long double Prix, string Intro, string Description, vector<vector<string>> ImgUrls) {
titre = new string;
intro = new string;
description = new string;
imgUrls = new vector<vector<string>>;
prix = new long double;
id = new size_t;
*id = nbAnnonces;
*titre = std::move(Titre);
*prix = Prix;
*intro = std::move(Intro);
*description = std::move(Description);
*imgUrls = std::move(ImgUrls);
}
There is no shortcut for allocating multiple variables from dynamic memory.
The functions for allocating memory return a single memory address (pointer). Each variable should have its own, unique, location in memory.
The syntax of the C++ language would need to change in order to support the dynamic memory functions returning multiple addresses (pointers).
One recommendation is to reduce the quantity of memory allocations. Ask yourself, "Do I really need to allocate from dynamic memory?" before allocating from dynamic memory.
Is there a way to write something like :
myInt, myOtherInt = new int;
Yes, two ways. But the first is more general than what you specifically asked for...
1. Prefer value-types over reference-types
If you don't know what these are: Value types and Reference Types (Wikipedia).
In some programming languages, almost all of your variables, function parameters, class fields, etc - are references. A prominent example of this is Java. But in C++ - especially these days - we prefer values to references unless there's a good reason not to use values directly. Value semantics are commonly used and well-supported in the language, and most work with them is easier. See also:
Why are pointers not recommended when coding with C++11
Specifically, that means that, when defining a struct or a class, we'll give it non-pointer members. In your case:
class Announcement {
public:
using url_type = std::string; // perhaps use a URL library?
using image_urls_container_type = std::unoredered_set<url_type>;
// I'm guessing the URLs aren't really ordered
std::string title;
std::string introduction;
std::string description;
std::vector<image_urls_container_type> image_urls;
// Are the images really a sequence of indices? Shouldn't this be something like
// std::unordered_map<image_id_type,image_urls_container_type> image_urls ?
long double prize;
std::size_t id;
Announcement() = delete;
// constructors here, if you like
}
Now, I'm not saying this is necessarily the best possible definition or that it fits all your needs. But if you define it this way, you get:
No need to use new, ever.
No need to delete anything.
No chance of memory leaks (due to this class)
2. Otherwise, use std::unique_ptr's
The std::unique_ptr<T> class lets you avoid having to manage memory yourself - it takes care of that. So if you make your members std::unique_ptr's, you can initialize the value they point to using get(), e.g.:
void foo(int x) {
auto p = std::make_unique<p>();
p.get() = x;
// do stuff with p
// ...
// no need to delete p at the end of the function
}
First Pre Answer Suggestion: don't do it.
Second Pre Answer Suggestion: avoid self-managed memory allocation/deallocation and use STL containers and/or smart pointers (std::unique_ptr, std::shared_ptr, etc.) instead
Answer: no, as far I know you can't write something as
int * myInt, myOtherInt = new int;
that allocate both variables (with different allocated pointers).
But you can wrap the pointers in a class or struct that automatically allocate the contained pointer (and, maybe, destroy it in the destructor).
Just for fun... if you write a wrapper as follows
template <typename T>
struct wrappPnt
{
T * pnt = new T{};
T & operator * ()
{ return *pnt; }
T const & operator * () const
{ return *pnt; }
~wrappPnt ()
{ delete pnt; }
};
you can write your Annonce this way
struct Annonce
{
wrappPnt<std::string> titre, intro, description;
wrappPnt<std::vector<std::vector<std::string>>> imgUrls;
wrappPnt<long double> prix;
Annonce (std::string Titre, long double Prix, std::string Intro,
std::string Description,
std::vector<std::vector<std::string>> ImgUrls)
{
*titre = std::move(Titre);
*prix = Prix;
*intro = std::move(Intro);
*description = std::move(Description);
*imgUrls = std::move(ImgUrls);
}
};
First Post Answer Suggestion: don't do it.
Second Post Answer Suggestion: avoid self-managed memory allocation/deallocation and use STL containers and/or smart pointers (std::unique_ptr, std::shared_ptr, etc.) instead

C++ When inserting heap Objects into std::map with insert() and another one exists who deletes the new one?

I'm trying to (somehow) cache multiple iterations on a std::map when I need to insert multiple values by using this method:
enum PROPERTY_TYPE
{
TYPE_BOOLEAN,
TYPE_INTEGER,
TYPE_UNSIGNED,
TYPE_FLOAT,
TYPE_STRING
};
struct Property {
Property(PROPERTY_TYPE type)
: type(type), bool_val(false), integer_val(0), unsigned_val(0), float_val(0.0f), string_val("")
{ }
PROPERTY_TYPE type;
bool bool_val;
int integer_val;
unsigned int unsigned_val;
float float_val;
std::string string_val;
};
std::map< std::string, Property* > _Properties;
void pushBool(std::string key, bool value)
{
std::pair< std::map< std::string, Property* >::iterator, bool > pItr;
pItr = _Properties.insert( std::pair< std::string, Property* >(key, new Property(TYPE_BOOLEAN)) );
// If the value doesn't exist then it's created automatically or the existion one is used.
pItr.first->second->bool_val = value;
pItr.first->second->integer_val = value ? 1 : 0;
pItr.first->second->unsigned_val = value ? 1 : 0;
pItr.first->second->float_val = value ? 1.0f : 0.0f;
pItr.first->second->string_val = value ? "true" : "false";
}
This is the fastest and safest way I can get it to work so far. However I'm interested in one little thing and that's the insert() function. When I call new Property(TYPE_BOOLEAN) I clearly create a new Property() that nobody controls it. And from what I read, std::map doesn't call delete on pointers when discard. And when I use this method of inserting the insert function uses the existing value if it already exists. So, Who deletes that newly created Property() if a value already exists and it's used instead of the new one?
pItr = _Properties.insert( std::pair< std::string, Property* >(key, new Property(TYPE_BOOLEAN)) );
Would this method be a waste of memory by introducing memory leaks?
Yes, that line can cause a leak.
Either store smart pointers, or check for existance before inserting. I would advise smart pointers. unique_ptr probably, to indicate ownership.
In this particular case, free store allocation is a bad idea, but I assume the real problem has a reason to store items there.
You're right - std::map doesn't buy in to the question of who deletes any pointers it stores - it expects the client code to take responsibility, or store a type that does that inherently. The simplest and often best way to do that - the way you'd use unless you'd seen a clear reason to do otherwise - is to store a "value semantic" type - one that takes care of its own life, and can be copied intuitively, behaving much like an int or other inbuilt type in that regard.
In your case, there's ostensibly no reason to use pointers at all... just
std::map< std::string, Property > _Properties;
If you don't care whether you're inserting a new element or updating an old one:
Property& p = _Properties[key];
p.bool_val = value;
p.integer_val = ... etc
Separately, if the idea is that a Property conceptually stores any one of those types of data, you may find boost::variant useful: http://www.boost.org/doc/libs/1_55_0/doc/html/variant.html

Managing objects returned from C++ function

I am wondering how one would go about returning a new object from a C++ function. For example, I have a SQLite wrapper which used to mix in Objective-C and I modifying it to be purely C++.
So, for example:
list<char*> * SqliteWrapper::RunQuery(const char *query)
{
list<char*> * result = new list<char*>();
//Process query
return result;
}
the issue that I can see in this, is that who owns the object? The calling class or the class that created the object? What is worse, is that this is very prone to memory leaks. If the caller object does not delete the newly created object, the app will end up with a memory leak.
Now that I think about this, this would make a lot of sense:
int SqliteWrapper::RunQuery(const char *query, list<char*>& result)
{
//Process query
return errorCode;
}
Are there any other approaches to this? I have been a C# programmer for a while and only now am starting to work heavily with C/C++.
Many programmers do this:
If it is a pointer that is returned, I am being given the object's identity (it's location in memory is unique) I must manage that. I am responsible for deleting it.
(Pointer = my job)
references however let you pretend you are being passed the object, to look at and use. you are not responsible for deleting these, something else is.
BUT:
"Naked pointers" may be frowned upon for code like this (it's very subjective) so some would say use a "unique_ptr" to that, these can be moved, and delete what they point to when deleted (unless the stuff is moved out of them), by returning one and not using it, it will be deleted.
(tell me if you want me to flesh this out, see also "shared_ptr" if multiple things have a pointer, this will delete what it points to when the last shared_ptr pointing to it is deleted)
Addendum 1
unique_ptr<list<char*>> SqliteWrapper::RunQuery(const char *query)
{
list<char*> * result = new list<char*>();
//Process query
return make_unique<list<char*>>(result);
}
Remember you can only move, not copy unique_ptrs
Well. You are right.
First example would be a bad style, since in such a code is hardly readable and it is hard to track bugs in it.
Usually people use the second approach with reference.
In the same way you can use pointer, allocating the return object before function call.
Third approach would be to use class instead of function. It is convinient if your function does complicated process with many parameters. In this case you store result as a data member of the class and ownership is obvious:
class SqliteWrapper {
...
class ProcessQuery {
public:
ProcessQuery():fQ(0),fP1(0){}
SetQuery(const char *query){ fQ = query; }
SetP1(int p1){ fP1 = p1; }
...
list<char*> GetResult(){ return fR; } // copy
int Run();
private:
const char *fQ;
int fP1;
...
list<char*> fR;
}
...
}
int SqliteWrapper::Process::Run()
{
//Process query
return errorCode;
}

c++ : alternative for Vector of references to avoid copying large data

I have spent some time looking for answers but didn't find anything that was satisfactory.
Just interested in how some more seasoned C++ people solve this kind of problem as now I am doing a little more production related coding than prototyping.
Let say you have a class that has say a unordered_map (hashmap) that holds a lot of data, say 500Mb. You want to write an accessor that returns some subset of that data in an efficient manner.
Take the following, where BigData is some class that stores a moderate amount of data.
Class A
{
private:
unordered_map<string, BigData> m_map; // lots of data
public:
vector<BigData> get10BestItems()
{
vector<BigData> results;
for ( ........ // iterate over m_map and add 10 best items to results
// ...
return results;
}
};
The accessor get10BestItems is not very efficient in this code because it first copies the items to the results vector, then the results vector is copied when the function is returned (copying from the function stack).
You can't have a vector of references in c__ for various reasons, which would be the obvious answer:
vector<BigData&> results; // vector can't contain references.
You could create the results vector on the heap and pass a reference to that:
vector<BigData>& get10BestItems() // returns a reference to the vector
{
vector<BigData> results = new vector<BigData>; // generate on heap
for ( ........ // iterate over m_map and add 10 best items to results
// ...
return results; // can return the reference
}
But then you are going to run into memory leak issues if you are not careful. It is also slow (heap memory) and still copies data from the map to the vector.
So we can look back at c-style coding and just use pointers:
vector<BigData*> get10BestItems() // returns a vector of pointers
{
vector<BigData*> results ; // vectors of pointers
for ( ........ // iterate over m_map and add 10 best items to results
// ...
return results;
}
But most sources say to not use pointers unless absolutely necessary. There are options to use smart_pointers and the boost ptr_vector but I rather try to avoid these if possible.
I do no that the map is going to be static so I am not too worried about bad pointers. Just one issue if the code will have to be difference to handle pointers. Stylistically this is not pleasant:
const BigData& getTheBestItem() // returns a const reference
{
string bestID;
for ( ........ // iterate over m_map, find bestID
// ...
return m_map[bestID] ; // return a referencr to the best item
}
vector<BigData*> get10BestItems() // returns a vector of pointers
{
vector<BigData*> results ; // vectors of pointers
for_each ........ // iterate over m_map and add 10 best items to results
// ...
return results;
};
E.g., if you want a single item then it is easy to return a reference.
Finally option is to simply make the Hash-map public and return a vector of keys (in this case strings):
Class A
{
public:
unordered_map<string, BigData> m_map; // lots of data
vector<string> get10BestItemKeys()
{
vector<string> results;
for (........ // iterate over m_map and add 10 best KEYS to results
// ...
return results;
}
};
A aTest;
... // load data to map
vector <string> best10 = aTest.get10BestItemKeys();
for ( .... // iterate over all KEYs in best10
{
aTest.m_map.find(KEY); // do something with item.
// ...
}
What is the best solution? Speed is important but I want ease of development and safe programming practices.
I would just go with a vector of pointers if the map is constant. You can always return const pointers if you want to avoid the data being changed.
References are great for when they work but there's a reason we still have pointers (for me this would fall under the category of being 'necessary').
I would do something similar to the following:
Class A
{
private:
unordered_map<string, BigData> m_map; // lots of data
vector<BigData*> best10;
public:
A()
: best10(10)
{
// Other constructor stuff
}
const vector<BigData*>& get10BestItems()
{
// Set best10[0] through best10[9] with the pointers to the best 10
return best10;
}
};
Note a few things:
The vector isn't being reallocated each time and is being returned as a constant reference, so nothing is allocated or copied when you call get10BestItems.
Pointers are just fine in this situation. The things you read about avoiding pointers were probably in relation to heap allocations, in which case std::unique_ptr or std::shared_ptr are now preferred.
This sounds like a job for boost::ref to me. Just change your original code slightly:
typedef std::vector<boost::ref<BigData> > BestItems;
BestItems get10BestItems()
{
BestItems results;
for ( ........ // iterate over m_map and add 10 best items to results
// ...
return results;
}
Now you're notionally only returning a reference to each item within your return vector making it small and cheap to copy (if the compiler isn't able to optimize away the return copy completely).
I usually use boost::range and I found it is invaluable in so many situations, especially the one you describe.
You can keep the range object and iterate over it, etc.
But I should mention I don't know what happens if you add/remove on object between when you get the range and when you use it, so you may want to check that out before using it.

how to convert iterator of list STL to instance (C++)

this is my first time using the list STL and i'm not sure if what i'm trying to do is possible.
I have class_B which holds a list of class_A, I need a function in class_B that takes an ID, searches the list for an instance with the same ID, and gets a pointer form the list to the instance in that list:
bool class_B::get_pointer(int ID,class_A* pointer2A){
list<class_A>::iterator i;
for(i=class_A.begin();i!=class_A.end();i++){
if((*i).get_id()==ID) {
\\pointer2A=(i);<---------------this is what I'm trying to do
return true;
}
}
pointer2A=NULL;
return false;
}
how do I perform this, is it possible to convert from iterator to instance ?
EDIT:
I'm using this function in a multi-threaded program and I can't return an iterator to the calling function since another thread might delete an element of the list.
Now that I have a pointer to my element(and lets say it's locked so it can't be deleted), and a different thread removed another element and performed a sort on the list, what will happen to the pointer I'm holding ? (I don't know how the list rearranges the elements, is done by copying the elements using a copy c'tor, or by another mean?).
Useless answer was the most helpful in my case (BIG thanks), and yes I should use a reference to the pointer since I'm planing to change it.
You should write this:
pointer2A= &*i;
Here *i returns the object whose address you can get by prepending & as : &*i.
Note that i is not same as &*i. See this topic for more general discussion:
Difference between &(*similarObject) and similarObject? Are they not same?
Anyway, I would suggest you to read the pointer itself as:
class_A* class_B::get_pointer(int ID)
{
//I assume the name of the list is objA, not class_A
for(list<class_A>::iterator i=objA.begin();i!=objA.end();i++)
{
if( i->get_id()==ID)
{
return &*i;
}
}
return NULL; //or nullptr in C++11
}
Or, in C++11, you can use std::find_if as:
auto it = std::find_if(objA.begin(),
objA.end(),
[&](class_A const &a){ return a->get_id() == ID;});
classA *ptr = NULL;
if ( it != objA.end())
ptr = &*it; //get the pointer from iterator
Make sure get_id is a const member function.
if(i->get_id()==ID) {
pointer2A=&*i;
return true;
}
iterators are designed to have similar semantics to pointers, so for example you can write i->get_id() just as if you had a pointer to A.
Similarly, *i yields a reference A&, and &*i converts that back into a pointer - it looks a bit clunky (it would be an identity operation if i were really a pointer), but it's idiomatic.
Note that this won't do what you presumably want anyway - the caller's class_A* pointer2A is passed by value, so only get_pointer's copy of the pointer is modified, and the caller won't see that value. Try this:
bool class_B::get_pointer(int ID, class_A *& pointer2A)
{
list<class_A>::iterator i;
for(i=class_A.begin();i!=class_A.end();i++) {
if(i->get_id()==ID) {
pointer2A=&*i;
return true;
}
}
pointer2A=NULL;
return false;
}
Now pointer2A is passed by reference, so the caller's copy gets modified inside your function.
BTW, you can read the parameter declaration class_A * & pointer2A right-to-left, as "pointer2A is a reference to a pointer to class_A".
If you have an iterator, you can get a raw pointer by simply dereferencing the iterator (which gives you a reference), and then taking the address of that (which gives you a pointer). So, in your case:
pointer2A = &*i;
This might seem like an odd, clumsy way to get a pointer, and it is. But you normally don't care about pointers when you are using the collections & iterators from the Std Lib. Iterators are the glue that hold the "STL" together. That's what you should be dealing with, by and large, rather than raw pointers.
The loop you've written above certainly gets the job done that you wish to accomplish, but there are better* ways to accomplish the same goal. (Better is a subjective term.) In particular, the <algorithm> library provides both std::find and std::find_if which do just what they say they do. They find something in a collection. find will find something that is equal to what you're looking for. find_if will find something that matches some criteria that you specify. The latter is the appropriate algorithm to use here, and there are two main ways to use it.
The first, more "traditional" approach is to use a functor:
struct match_id : public std::unary_function<bool, class_A>
{
match_id(int ID) : id_(id) {};
bool operator()(const class_A* rhs) const
{
if( id_ == rhs->get_id() )
return true;
else
return true;
};
/* ... */
list<class_A>::iterator it = std::find_if(objA.begin(), objA.end(), match_id(ID));
This approach works in C++03 or C++11. Some people don't like it because it is rather verbose. I like it, on the other hand, because the actual buisness logic (the find_if call) is quite succinct and more expressive than an explicit loop.
In C++11, you can use a lambda in place of the functor:
unsigned ID = 42;
std::find_if( objA.begin(), objB.end(), [&ID](const class_A& rhs) -> bool { return rhs.get_id() == ID; } };
There's a tradeoff here. On the pro side, you don't have to write 10 or so lines of code for the functor, but on the con side, the lambda syntax is funky and takes a bit of getting used to.