1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

Ticket #2881 (new enhancement)

Opened 23 months ago

Last modified 23 months ago

container use after clear

Reported by: tehuser Owned by: noone
Priority: Milestone:
Component: New check Keywords:
Cc:

Description

Sorry if this is a duplicate. I used the search to find out, but couldn't see any.

#include <map>
#include <iostream>

using namespace std;

int main()
{
	map<int, int> m;

	m[0]=2;
	m[1]=4;
	m[2]=-2;
	m[3]=-5;


	m.clear();

	cerr << m[2] << endl;
}

$gcc test.cpp -o test -Wall --pedantic -lstdc++
$cppcheck --enable=all test.cpp
Checking test.cpp...
$cppcheck --version
Cppcheck 1.48

Change History

Changed 23 months ago by hyd_danmar

Good suggestion, thanks! I am pretty sure there is no ticket about this.

It shouldn't be too hard to implement this.

Changed 23 months ago by kimmov

This is valid and defined behavior for the std::map.

Reading documentation always helps:
http://www.cplusplus.com/reference/stl/map/operator%5B%5D/

[x being the index to access]

If x does not match the key of any element in the container,
the function inserts a new element with that key and returns
a reference to its mapped value.

There is even an example code doing this.

Changed 23 months ago by tehuser

I don't think thats right. This is only true if you

map[value] = key;

and value does not exist in the map. Then it will insert the value, key pair into the map. This does not happen if you do

  something = map[value];

Or you could simply alter the example and use .at instead, which does not do insertion, or change the map to a vector.

Changed 23 months ago by tehuser

Sorry, more correct semantics:

map[key] = value;

will insert

and

newvalue = map[key];

wont insert.

Changed 23 months ago by kimmov

So you question that reference's correctness?

Changed 23 months ago by tehuser

I am questioning the relevance of this reference to this ticket -- it does not cover the case here. Simply alter my example to use "at" instead, if you wish -- this should be a completely unambiguous result. Or alternatively, alter the container.

here are some revised programs:

#include <vector>
#include <iostream>

using namespace std;

int main()
{
	vector< int> m;

	v.push_back(2);
	v.push_back(1);
	v.push_back(-2);
	v.push_back(-5);


	m.clear();

	cerr << m[2] << endl;
}

And also

#include <map>
#include <iostream>

using namespace std;

int main()
{
	map<int, int> m;

	m[0]=2;
	m[1]=4;
	m[2]=-2;
	m[3]=-5;


	m.clear();

	cerr << m.at(2) << endl;
}

Changed 23 months ago by tehuser

errata (actually using a compiler this time):

#include <vector>
#include <iostream>

using namespace std;

int main()
{
	vector< int> m;

	m.push_back(2);
	m.push_back(1);
	m.push_back(-2);
	m.push_back(-5);


	m.clear();

	cerr << m[2] << endl;
}


Note: See TracTickets for help on using tickets.