Hello everybody,
I am not able to fix a Segmentation Fault that raises inside the find method of an STL map. Perhaps you can give me some clue.
The map stores a one to many relationship between Usage and Resources. I use this struct to store the UsageId (the ResourceId is analogous):
typedef std::string UsageName;
typedef unsigned int UsageIndex;
struct UsageId {
UsageName name;
UsageIndex index;
UsageId(UsageName, UsageIndex = 0);
UsageId();
bool operator<(const UsageId &) const;
bool operator==(const UsageId &) const;
};
bool UsageId::operator<(const UsageId &other) const {
if(name < other.name)
return true;
else if(name > other.name)
return false;
else {
return ((unsigned int)(index) < (unsigned int)(other.index));
}
}
bool UsageId::operator==(const UsageId &other) const {
return ( ( name == other.name ) &
( (unsigned int)(index) == (unsigned int)(other.index) ) );
}
UsageId::UsageId(): name(""), index(UsageIndex(0)) {}
UsageId::UsageId(UsageName _name, UsageIndex _index): name(_name), index(_index) {}
As you can see I provide a default constructor that set the name and index to "" and 0 respectively.
Now the class that stores the map:
class ResourceAssignationTable {
public:
void assign(UsageId usage, ResourceId resource);
ResourceId get_assigned_to(UsageId usage);
private:
std::map<UsageId, std::list<ResourceId> > assigned;
}
ResourceId ResourceAssignationTable::get_assigned_to(UsageId usage) {
map<UsageId, list<ResourceId> >::const_iterator it_assigned;
it_assigned = assigned.find(usage);
if(it_assigned == assigned.end()) throw "Usage not found";
const list<ResourceId> &assigned = (*it_assigned).second;
return *assigned.begin();
}
The Segmentation Fault raises inside the get_assigned_to method, concretely in the line:
it_assigned = assigned.find(usage);
I debugged that method and I found the exception raises in the comparison between names (strings) in the first line of the comparison method of UsageId:
bool UsageId::operator<(const UsageId &other) const {
if(name < other.name)
return true;
else if(name > other.name)
return false;
else {
return ((unsigned int)(index) < (unsigned int)(other.index));
}
}
The variable "other" contains the UsageId provided to the find method, as expected, but the member variables "name" and "id" seems to be uninitialized and contain garbage. So when the comparison operator tries to access the string "name" it raises the segmentation fault. I don't understand how UsageId object can contain garbage since I provide a default constructor.
I use a large test, and this method works perfectly for hundred of calls. But it always raises the exception in the same point, when asked for a particular UsageId. This UsageId was requested early in the test and the method worked!
Well, that's all. Any clue will be welcomed.
Regards
Chema
[Edited by - chema on September 18, 2007 8:21:13 AM]
///////////////////////////// Good luck, // // you will need it! /////////////////////////////Chema