2

I have a std::unordered_map<char, Node*> inside my custom structure. I want to initialize it with an empty map. Did I do something wrong? I have tried 2 kinds of initialization, both of them give me same result.

The following statement:

newStructure->map = unordered_map<char, Node*>();

sometimes results in success and the size of this map is 0, which it should be. Most of the time, this would fail during the initialization, and the following error would be generated with no initialization of the map:

malloc: pointer being freed was not allocated

This would give me extreme huge size of the initial std::unordered_map. The size of the map could be 88029716824088.

How can I correctly initialize an empty std::unordered_map struct?

My structure is defined like this:

struct Node {
    char letter;
    unordered_map<char, Node*> next;
    bool hasEnd;
    static Node* init(char);
}

And, my initializer is defined like this:

Node* Node::init(char letter) {
    Node *newNode = (Node*) malloc(sizeof(Node));
    newNode->letter = letter;
    newNode->hasEnd = false;
    return newNode;
};

Sometimes, the size of the next would be very huge number.

Azeem
  • 11,148
  • 4
  • 27
  • 40
Judgelight
  • 81
  • 1
  • 8
  • if u define a map it is already empty. – user1438832 Oct 16 '17 at 03:48
  • @user1438832 but the size of the map could sometimes go very large. How could that possible? – Judgelight Oct 16 '17 at 03:50
  • 4
    You are not using `malloc` to allocate C++ objects, are you? [In what cases should I use malloc vs new?](https://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-vs-new) – Bo Persson Oct 16 '17 at 04:24
  • @BoPersson, thank you so much. I just come from C, and I'm not very familiar with the detail of the C++. The map work normal now. I think I need to find out the difference between `new` and `malloc` now. – Judgelight Oct 16 '17 at 04:32
  • 2
    @Judgelight - It's rather simple really. Don't use `malloc` and you'll be fine. If you wonder "but what if I need to use `malloc`?" then you'll have to wait a long time until you have a real need. And by then you'll know enough C++ to use it wisely. – StoryTeller - Unslander Monica Oct 16 '17 at 06:03

2 Answers2

1

You need to use new instead of malloc when creating C++ objects.
When you create a map it is already empty by default.

You can read more here: In what cases do I use malloc and/or new?

roman
  • 103
  • 1
  • 6
0

The actual failure and the strange map size happens because when you do this:

Node *newNode = (Node*) malloc(sizeof(Node));

You are saying that there struct Node at the address you got from malloc.

The problem is that the constructor for the unordered_map will not get called. And malloc is not required to return zeroed memory.

This means that internals of unordered_map will simply be whatever values are there in the memory returned by malloc. Also keep in mind that zeroes also might not be ok for correct initialization of unordered_map internals. It will only be correctly initialized if its constructor gets called. This you a Node with a broken unordered_map member

Then when you do:

newStructure->map = unordered_map<char, Node*>();

The destructor for the unordered_map will get called, because you are actually replacing the unordered_map which you said is already there with a new one. Since the values in the memory you got from malloc might not be 0 and the unordered_map internals might contain a pointer to some memory that gets allocated when its constructor gets called, the destructor will try to deallocate some random value, causing the error you are seeing.

Jaka
  • 1,205
  • 12
  • 19