map with char*

Hello everybody,

I am having a problem and I am not sure why.
I want a map with char strings and whenever we try to add the same string the map should delete this string and increments the map element's value.

But for some reason it does not increment the element and adds the same string in the map.

I tried to keep the code example below small because I don't want to tire you without a reason.

I managed to make it work with std::string but now I wanted to train with C style strings also.

Thanks in advance.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <cstring>
#include <map>

typedef std::map<char*, int> Map_Type;
static Map_Type  pointer_count;

class StringHolder
{
public:
	StringHolder(const char* a_Str)
	{
		str = new char [strlen(a_Str)+1];
		strcpy(str, a_Str);
		Map_Type::iterator iter = pointer_count.find(str);
		if (iter != pointer_count.end())
		{
			++iter->second;
		}
		else
		{
			pointer_count.insert(std::pair<char*, int>(str, 1));
		}
	}
	~StringHolder()
	{
		delete str;
	}
	void PrintAll()
	{
		for (Map_Type::iterator iter = pointer_count.begin(); iter != pointer_count.end(); ++iter)
		{
			std::cout << "String " << iter->first << " has : " << iter->second << " pointer(s), the address is: " << &(iter->first) << std::endl;
		}
	}
private:
	char* str;
};

int main()
{
StringHolder alpha("Anna");
StringHolder beta("Anna");
beta.PrintAll();

return 0;
}
Last edited on
For some reason it worked when I had my str and map's first element as const char*
but the problem is that I don't want str to be const as in the rest of the program I want to append it.
each new'd array has a different memory address (they can only be reused after you delete[] some -- note that your "delete str;" is an error). Those memory addresses are what you're using as map keys. Thus, the pointer you get from new[] is never present in the map already, so you add it to the map every time.

Use strings instead:
1
2
3
std::map<string, int> Map_Type;
...
string str(a_Str);

Or provide a suitable comparison function to your map.
Last edited on
Hey, thank you for your reply. Yes strings are much easier to handle, I am aware of that and I have already made it work with strings. But part of my task is to do it with chars. So do you have any good idea on how to do it? What do you mean by "Or provide a suitable comparison function to your map."?
Last edited on
I mean something like

1
2
3
4
5
6
7
8
struct CompareCStrings 
{
    bool operator()(const char* lhs, const char* rhs) const {
        return std::strcmp(lhs, rhs) < 0;
    }
};

std::map<char*, int, CompareCStrings> Map_Type
What do you mean by "Or provide a suitable comparison function to your map."?


http://cplusplus.com/reference/stl/map/map/

The example code shows how to use a custom comparison function.
Thank you very much!
The problem has been solved.
Topic archived. No new replies allowed.