I was investigating how map handles custom types and I came across some odd behavior.
I created a custom type ´ComplexType´ that has 1 member, a pointer to an int. I first compared using the value of this int, which gave the expected behavior.
#include <iostream>
#include <map>
struct ComplexType
{
ComplexType(int i): index(new int(i)){
};
ComplexType(const ComplexType& cT): index(new int(*cT.index)){
}
~ComplexType(){
if(index){
delete index;
}
}
bool operator<(const ComplexType cT) const
{
return *index < *cT.index;
}
int* index;
};
int main(){
int pi[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 8};
std::map< ComplexType , int > container;
for(int i = 0; i < 12; ++i){
container[ComplexType(i)] = pi[i];
}
std::cout << "Loop map, size: " << container.size() << std::endl;
for(auto it = container.begin();it != container.end(); it++){
std::cout << "Show index map, size: " << container.size() << std::endl;
std::cout << *it->first.index << std::endl;
}
return 0;
}
With the output:
Loop map, size: 12
Show index map, size: 12
0
Show index map, size: 12
1
Show index map, size: 12
2
Show index map, size: 12
3
Show index map, size: 12
4
Show index map, size: 12
5
Show index map, size: 12
6
Show index map, size: 12
7
Show index map, size: 12
8
Show index map, size: 12
9
Show index map, size: 12
10
Show index map, size: 12
11
Now I changed my compare function to compare on the address of the pointer.
#include <iostream>
#include <map>
struct ComplexType
{
ComplexType(int i): index(new int(i)){
};
ComplexType(const ComplexType& cT): index(new int(*cT.index)){
}
~ComplexType(){
if(index){
delete index;
}
}
bool operator<(const ComplexType cT) const
{
return index < cT.index;
}
int* index;
};
int main(){
int pi[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 8};
std::map< ComplexType , int > container;
for(int i = 0; i < 12; ++i){
container[ComplexType(i)] = pi[i];
}
std::cout << "Loop map, size: " << container.size() << std::endl;
for(auto it = container.begin();it != container.end(); it++){
std::cout << "Show index map, size: " << container.size() << std::endl;
std::cout << *it->first.index << std::endl;
}
return 0;
}
I expected this to result in a random order based on what addresses the pointer got on the heap. Instead I got the following:
Loop map, size: 12
Show index map, size: 12
1
Show index map, size: 12
0
I compiled using g++:
g++ (GCC) 5.3.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\randomness map>g++ -std=c++11 -o mapConstructionComplexType mapConstructionComplexType.cpp
\randomness map>g++ -std=c++11 -o mapConstructionComplexTypePointerCmp mapConstructionComplexTypePointerCmp.cpp
Can anyone explain this odd behavior?
Aucun commentaire:
Enregistrer un commentaire