I have a map in C++ as:
std::map<std::pair<std::string, std::string>, std::unique_ptr<T>> my_map;
Will using my_map.clear cause memory leak issue ?
Related
For example I've got a map like this:
std::map<std::map<pair<int, int>, pair<int, int> >, int> mp;
How do I insert/access element into/in that map?
For inserting I've tried with
// using nested map
std::map<pair<int, int>, pair<int, int> > mp2;
mp2.insert(make_pair(1,2), make_pair(3,4));
mp.insert(make_pair(mp2, 1));
For accessing the elements, I couldn't insert element into the map so I don't know if I did it right or wrong, but I think it is gonna be like this
mp[[1,2],[3,4]];
And the compiler throws a lot of errors . Some even navigate me to the implementation code of std::map, or to be more specific, the stl_tree.h thing.
What's wrong? I'm just a mere beginner so any help would be genuinely appreciated.
In addition, this is my homework. Basically I have to store coordinates like (x,y) and (i,j) to form a path into a container, and I've tried with vectors but I couldn't pass the time limit.
Please reconsider your choice of data structure. Using std::map as a key to std::map will incur large overheads due to necessity of creating temporary keys to compare (when accessing outer map elements). It's highly unlikely that it will help you get through the time limit of yours.
std::map::insert requires a ready std::pair<Key, Value>, which means you need to wrap your arguments in one more std::make_pair
mp2.insert(std::make_pair(std::make_pair(1,2), std::make_pair(3,4)));
Or you can replace insert with emplace
mp2.emplace(make_pair(1,2), make_pair(3,4));
To access elements you must construct a temporary map to be used as a key:
mp[{{{1,2},{3,4}}}]; //extra {} required
See it online
As pointed out by #Yksisarvinen, you should reconsider using a map as a key to another map.
That being said, I guess you forgot an enclosing std::make_pair() at:
mp2.insert(make_pair(make_pair(1,2), make_pair(3,4)));
For accessing that, you'd need to do something like:
template <class K, class V>
std::map<K, V> make_map(std::pair<K, V>&& pair)
{
return std::map<K, V> { pair };
}
mp[make_map(make_pair(make_pair(1 ,2), make_pair(3 , 4)))]
But beware that this is very inefficient!
In c++, I would like to insert a vector in a map.
The key of the map is a pair of string and int, and the value of one is a vector.
I am writing down the following code, however it seems that the vector is not inserted into the map.
Is the syntax of the code is wrong?
If so, could you tell me correct one?
map<pair<string, int>, vector<string> > my_map;
vector<string> v;
v.push_back("abcde");
my_map.insert(make_pair(make_pair("aaa",1),v));
You have used the v_pre while vector is of name v:
my_map.insert(make_pair(make_pair("aaa",1),v_pre));
The correct code should be:
my_map.insert(make_pair(make_pair("aaa",1),v));
Here is an example :
pair< map<int, string>, map<int, string> > test;
test = data;
So do i need to call clear method before assign? Like this :
pair< map<int, string>, map<int, string> > test;
test.first.clear();
test.second.clear();
test = data;
Or first example is correct without memory leaks?
http://www.cplusplus.com/reference/map/map/map/
Map constructor - constructs empty container with no elements.
Pair -Constructs a pair object with its elements value-initialized.
So, my guess is that there is no memory leak, plus you are not allocating any memory there so.
The program has the following input data:
std::map<std::string, std::vector<int> >
Now I need to convert this data structure into the following:
std::map<int, std::vector<int> >
Fo example:
"key1" => 1
"key2" => 20
etc.
Only the key type is changed, the mapped value is unchanged.
The question is that how I can reuse the mapped key std::vector<int> effectively so that the mappped value is not copied since there is no need to do so.
Here are two ideas that come to my mind:
////////////////////////////////////////////////////
Solution 1>
redefine the interface
from
std::map<int, std::vector<int> >
to
std::map<int, std::vector<int>* >
////////////////////////////////////////////////////
Solution 2>
redefine the interface
from:
std::map<std::string, std::vector<int> >
std::map<int, std::vector<int> >
to:
std::map<std::string, boost::shared_ptr<std::vector<int>> >
std::map<int, boost::shared_ptr<std::vector<int>> >
In both cases, the cost of the copy is simply a copy of a pointer.
Any comment is appreciated
C++11 provides move-operations to move one object to another without copying. VS 2010 should have the necessary machinery implemented. With this, assuming you have a mapping for old to new keys, you can remap the data like this:
std::map<std::string, std::vector> m1;
std::map<int, std::vector> m2;
std::map<std::string, int> keymap;
for (auto i=m1.begin(); i != m1.end(); ++i)
{
m2[keymap[i->first]] = std::move(i->second);
}
Now, all vectors have been moved to a new map leaving the map m1 in an undefined, but destructible state.
If C++11 (as available in VS2010) is not an option, swap the new map with the old one:
std::map<std::string, std::vector> m1;
std::map<int, std::vector> m2;
std::map<std::string, int> keymap;
for (std::map<std::string, std::vector>::iterator i=m1.begin(); i != m1.end(); ++i)
{
m2[keymap[i->first]].swap(i->second);
}
Just a quick question, if you have say:
using namespace std;
map< int, vector< string > > map1;
or maybe even:
map< int, map< int, vector< string > > > map2;
and just so you get the right idea:
map< int, map< int, map< int, vector< string > > > > map3;
if I do just:
map1.clear();
map2.clear();
map3.clear();
Is it safe in that it will empty everything in the map and its nested maps, vectors, lists, etc.?
Note:
I know if you use pointers you need to manually go through and delete or if the map goes out of scope it should be fine too I'm only particularly interested in this case when in scope and on the stack.
Yes, a map will destruct all components.
If its components are STL containers, their destructors will clear the containers.
Read more about STL containers notably about destructor of std::map
Yes this is perfectly safe. STL containers take care of memory management.
However, if you store pointers to objects which you allocated youself, you also have to delete them yourself:
std::vector<MyClass*> vec;
vec.push_back(new MyClass());
vec.clear(); // you get a memory leak here because you did not delete the object you allocated.