Adding an element <string, pointer> to boost unordered hashmap - c++

I am using boost unordered hashmap in C++ and I am unable to add elements to my hash map (my program has a segmentation fault). I am very new to C++ and the majority of my code (except the hash map handling) is C code. Could you please point out the problem.
// my simplified code
struct Record
{
char *data;
};
typedef boost::unordered_map<std::string, std::vector<Record*> > MAP;
typedef std::pair<std::string,std::vector<Record*> > PAIR;
struct OuterRelation
{
short num_keys;
short join_key_ndx;
MAP hash_table;
};
OuterRelation *outer_relation = (OuterRelation *) malloc (sizeof(OuterRelation)) ;
Record *new = (Record *) malloc(sizeof(Record));
new->data = "somestring";
outer_relation->hash_table[new->data].push_back(new);
The problem is in the last line.

STOP USING malloc. That's for C. Correct syntax would be:
OuterRelation *outer_relation = new OuterRelation;
Your use of malloc has allocated enough space for the OuterRelation struct alone. This might be enough if the struct contained only plain-old-data. However, the hash_table member is a class and using malloc has left it uninitialised.
new is (at its most basic) a combination of malloc and a call to the new'd object's constructor. The constructor for your struct will in turn call the constructors of its members, including the map. The map's constructor will initialise its data members.
You also need to stop using new as a variable name. That clashes with the new C++ keyword.

Related

c++ segmentation fault when dereferencing a pointer to a vector of structures

So I'm creating a closed-hashing hash table for a class and I have a structure
struct Example {
string key;
string data;
Example() { key = "000"; }
};
and a class which contains a member that points to a vector of structures, a constructor, and a function I'll be using to illustrate the problem.
class hash_table {
private:
vector<Example>* hash;
public:
hash_table(int size);
void dummy_method();
};
It is meant to dynamically allocate the number of structures in the vector based on user/file input.
hash_table :: hash_table ( int size=10 )
{
//initialize vector
vector<Example> * hash = new vector<Example>(size);
//test objects
for(int i=0;i<size;i++)
cout<<(*hash)[i].key<<endl;
}
the above code appears to initialize the 10 members, as it prints out "000"
ten times.
however, once I try this by calling dummy_method-
void hash_table::dummy_method() {
cout<<(*hash)[0].key<<endl;
}
I get a segmentation fault
I'm pretty sure this isn't even the correct way to do this, but I've been looking/tinkering forever and I can't seem to find a solution. I absolutely have to use a pointer to a vector of structures however, and I'm pretty sure I'm supposed to be dynamically allocating each of those structures as well (somehow). Thanks for any help.
(also, yes, we actually HAVE to use namespace, thus no std anywhere)
vector<Example> * hash = new vector<Example>(size); expression will initialize a local variable with name hash, not a hash_table::hash member (which is left uninitialized).

How to avoid memory leaks, with C++ with STL containers?

code snippet below:
//container declared
map<string, structA*>& aMap;
// allocation and insertion to container
structA *item = new structA();
aMap["arrDevAddr"] = item;
However I iterate and free the map value (pointer) at the end of the map getting used.
Now, due to above code snippet, valgrind is flagging me as "definitely leaked" message.
I want to clarify, the general principle of coding to avoid memory leak. As per my understanding, in (C++ coding):
when we allocate a memory, we are entitled to free it aswell, limted by the overall span of code.
when we keep the allocated memory in some container (e.g. map here), we still need to retain those pointers (allocations), until the map is using those pointers.
which means, allocate >> add pointer to container >> usage of pointers in the map >> ensure "deleting/freeing" the struct-pointers, when the map use is over, or if the map is contained in some object, then in the object's "destructor", map should be iterated and struct-pointers should be freed.
correct me, if I am wrong in my understanding.
SECOND CASE:
class A{
...
map<string, structA*>& aMap;
...
}
now in some other class, the map is inserted with value as;
if(..)
{ structA item;
aObj->aMap["arrDevAddr"] = &item;
}
...
Now, in this case, as "item" is local to the scope, will the map be containing the "dangling references"? If not, how?
In such scenario's what should be the way to ensure, we avoid any memory-leaks while coding?
Don't delete or free things yourself. Always use a memory-managing class- these are completely immune to memory leaks and such related problems unless you work very hard to do something very stupid.
In this case something like unique_ptr would be fine, or even just storing structA by value.
You would avoid memory leaks by storing a std::unique_ptr rather than a raw pointer:
#include <iostream>
#include <map>
#include <memory>
#include <string>
struct structA {};
using structA_ptr = std::unique_ptr<structA>;
//container declared
std::map<std::string, structA_ptr> aMap;
using namespace std;
int main()
{
aMap.emplace("bob", structA_ptr { new structA {} });
return 0;
}

initialization new map and set in c++

Hi i am doing my homeworks and i have a problem.
I need diferents maps and set in the application and i want reuse some variables.
I have this global variables
map<char,set<char> > IAF; //I Am Father
map<char,int> NBM; //Number Before Me
set<char> WCR; //Who can run
and every time in the main i need reset this variables.
I have done two things:
IAF = new map<char,set<char> >;
and
IAF = map<char,set<char> >;
But any has run.
Can someone help me?
use
IAF.clear()
NBM.clear()
WCR.clear()
(Edit: references to the spec and caveats)
map::clear()
set::clear()
Note that if you're storing pointers, clear() will remove the pointers, but it will not delete the memory pointed to by the pointers.
map<char,set<char> > IAF;
This is a definition of variable. This is not a pointer. If you want to do some kind of initialization you can use one of supported methods, e.g:
std::copy( differentContainer.begin(), differentContainer.end(), IAF.begin());
or
while( ...) {
IAF.insert( ...);
// or
IAF[ key] = value;
}
To delete the content of map you can do (this will not automatically delete memory pointed to by pointer in map - if you store pointers, use a smart pointers then):
IAF.clear();
In addition to the previous answers which are fairly clear. The new keyword, that you used at some point, is to allocate memory for a pointer.
map<char, set<char> > *IAF = new map<char, set<char> >;
//...
// free the memory
delete IAF;
Check the Dynamic memory allocation for more information and to understand when and how to use pointers.
Also, using
IAF = map<char,set<char> >;
Is incorrect. The map<char, set<char> > is a class name (combined with templates generic programming, see the answer to What is the meaning of "generic programming" in c++? ) and hence you cannot assign it to a variable in this way. What you want to do is to call the constructor that will return an instance of that class:
IAF = map >();
However, doing it this way is not efficient at all. It creates a temporary object, destroys IAF, copies the temporary, and then destroys the temporary (unless you are using C++11 and in this case you use move, but still...). So, it's better to use the clear() as stated by the other answers.

Which container to use for String-Interning

My goal is to do string-interning. For this I am looking for a hashed
container class that can do the following:
allocate only one block of memory per node
different userdata size per node
The value type looks like this:
struct String
{
size_t refcnt;
size_t len;
char data[];
};
Every String object will have a different size. This will be accomplished with
opereator new + placement new.
So basically I want to allocate the Node myself and push it in the container later.
Following containers are not suitable:
std::unordored_set
boost::multi_index::*
Cannot allocate different sized nodes
boost::intrusive::unordered_set
Seems to work at first. But has some drawbacks. First of all you have to allocate
the bucket array and maintain the load-factor yourself. This is just unnecessary
and error-prone.
But another problem is harder to solve: You can only search for objects that have the
type String. But it is inefficient to allocate a String everytime you look for an entry
and you only have i.e. a std::string as input.
Are there any other hashed containers that can be used for this task?
I don't think you can do that with any of the standard containers.
What you can do is store the pointer to String and provide custom hash and cmp functors
struct StringHash
{
size_t operator() (String* str)
{
// calc hash
}
};
struct StringCmp
{
bool operator() (String* str1, String* str2)
{
// compare
}
};
std::unordered_set<String*, StringHash, StringCmp> my_set;
Your definition for String won't compile in C++; the obvious
solution is to replace the data field with a pointer (in which
case, you can put the structures themselves in
std::unordered_set).
It's possible to create an open ended struct in C++ with
something like the following:
struct String
{
int refcnt;
int len;
char* data()
{
return reinterpret_cast<char*>(this + 1);
}
};
You're skating on thin ice if you do, however; for types other
than char, there is a risk that this + won't be
appropriately aligned.
If you do this, then your std::unordered_set will have to
contain pointers, rather than the elements, so I doubt you'll
gain anything for the effort.

C++ memory management for a vector with variable length items

Take a variable length struct (if this were a real program, an int array would be better):
#include <vector>
struct list_of_numbers(){
int length;
int *numbers; //length elements.
};
typedef std::vector<list_of_numbers> list_nums; //just a writing shortcut
(...)
And build a vector out of it:
list_nums lst(10); //make 10 lists.
lst[0].length = 7; //make the first one 7 long.
lst[0].X = new int[7]; //allocate it with new[]
(...)
The above works for g++ in ubuntu. The new() calls are needed to avoid segfaults. Can the lst vector be deleted all at once when it is no longer needed, or will the new calls cause a memory leak? It would be tedious to manually delete() all of the parts called with new().
The typical ways to do this in C++ would be to define constructors and destructors and assignment operators for the list_of_numbers struct that take care of the memory management, or (much better) use a std::vector<int> for the numbers field and get rid of the length field.
But if you do that, you may as well get rid of the struct entirely, and just do this:
#include <vector>
typedef std::vector<int> list_ints;
typedef std::vector<int_ints> list_lists;
(...)
list_lists lst(10); // make 10 lists.
lst[0].resize(7); // set length of the zeroth list to 7
Why not just use a vector of vector of int? That's it's job. You should not be calling new outside of a dedicated class.
In general, you would want to put cleanup code in the destructor of the object (~list_of_numbers()) and memory creating code in the constructor (list_of_numbers()). That way these things are handled for you when the destructor is called (or when the object is created).