std::string in std::map clear error

hey im using this an i cant find what im doing wrong
my program crashes when EraseLastError function is called

1
2
3
4
5
struct STATSSTRUCT
{
	std::string		LastError;
	int				SomeInt;
};


 
std::map< std::string, std::map<std::string, STATSSTRUCT*> > Stats;


1
2
3
4
5
void EraseLastError(const char* Name, const char* next)
{
	if (!Stats[Name][next]->LastError.empty())
		Stats[Name][next]->LastError.clear();
}


only thing i can maybe think is that my map hasnt set [Name][next] yet in that case how do i check if its set?


Edit:
ok i think i have worked this out
is this code right?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void EraseLastError(const char* Name, const char* next)
{
	for (auto it = Stats.begin(); it != Stats.end(); ++it)
	{
		if (it->first == Name)
		{
			for (auto ii = Stats[it->first].begin(); ii != Stats[it->first].end(); ++ii)
			{
				if (ii->first == next)
					Stats[Name][next]->LastError.clear();

				return;
			}
		}
	}
}
Last edited on
The point of the operator[] of the map is that it creates an entry if it doesn't exist.

In your case: If either Name or next does not exist in your map a new entry with a NULL pointer to STATSSTRUCT is created. You program will crash when you try to access this invalid pointer ->LastError

only thing i can maybe think is that my map hasnt set [Name][next] yet in that case how do i check if its set?
Use the find() function of map:

http://www.cplusplus.com/reference/map/map/find/
cant get this working is what i posted above right?
i tried it like that with find function 2
You are not even using the find function.

1
2
3
4
5
6
7
8
9
10
11
12
// Check if Stats[Name] exists
auto it = Stats.find(Name);
if (it != Stats.end())
{
	// Check if Stats[Name][next] exists
	auto it2 = it->second.find(next);
	if (it2 != it->second.end())
	{
		// No point in checking if LastError is empty first.
		it2->second->LastError.clear(); 
	}
}
i said i tried the above code an i tried it with the find function as well.
i think i now have it kind of working but i have another function that sets the data.
i was calling it different before an it worked like this
 
Stats[Name][next].LastError = "test error"


but when i changed it to pointer an used it like this
it crashed with access violation
 
Stats[Name][next]->LastError = "test error"
Last edited on
So why did you change it to a pointer? If you use a pointer you will have to allocate the STATSSTRUCT object and update the pointer in the map yourself.
because i always see everyone using things like this with pointers
an thought it looked neater.
an plus kinda a learning curve.
that way i would know what way i like the best
Fair enough. Use it as a learning exercise. You will notice that pointers doesn't make things "neater" and that they should not be used unless necessary because it complicates things and increases the risk of bugs.

So now if you use pointers you need to make sure that Stats[Name][next] points to a STATSSTRUCT object before you can do
 
Stats[Name][next]->LastError = "test error"


One way is to allocate an object using new.
 
Stats[Name][next] = new STATSSTRUCT;

And then you should also remember to delete the object when you are done using it.
Last edited on
cant get this working is what i posted above right?
Looks like it is right, but I'd recommend Peters solution.

but when i changed it to pointer an used it like this
it crashed with access violation
The same problem. When you have the whole struct it creates an empty struct. When you have a pointer it creates a NULL pointer.
Thanks heaps for the help.
kinda understand it an have working with pointers.

so im better off not using pointers?
when is the best time to use pointers in this kind of thing im doing?
when is the best time to use pointers in this kind of thing im doing?

Principally, for when you want to use dynamically allocated memory on the heap, rather than having your data in local variables being copied around.

Also, using pointers can ensure that all code that accesses or changes the contents of these structures is using the same memory, rather than using separate copies of the data. When you put a struct into your map, it's actually creating a new copy of that struct that gets stored in the map, separate from the one in the calling code.



Topic archived. No new replies allowed.