I been sitting over this problem quiet a few hours now and can not find a solution. I try to get rid of some Custom Array classes and want to change them to std::vector.
I have a class member declared like this:
std::vector<BaseCluster *> baseClusters;
In the class constructor I do not initialize the vector to a certain size. I leave it as is, uninitialized. Before, I tried to initialize if to a certain size (to gain some performance and prevent many reallocations), but that gave me problems accessing the elements in a loop (eg. printing them out). I guess it is due to the initialization of the objects with the default constructor (of type BaseCluster) as NULL-Objects ??
However, in a loop I fill the vector with objects like this
baseClusters.push_back(new BaseCluster(current, score));
After the loop finishes I do some cleanup of objects that are not interesting:
for (unsigned int i = 0; i < baseClusters.size(); i++) {
// --- testing
if (baseClusters.at(i) == NULL) {
wcout << i << ". object is NULL" << endl;
}
if (
((BaseCluster *) baseClusters.at(i))->getNode()->getSuffixedDocumentsCount() < minimalGroupSize
) {
baseClusters.erase(baseClusters.begin() + i);
}
if (i >= noMoreBaseClustersThan) {
baseClusters.erase(baseClusters.begin() + i);
}
}
Now I sort the vector (should be sorted by score descending) and here I have a problem:
1.) using the sort as
sort(baseClusters.begin(), baseClusters.end());
doesn’t sort at all, also my implemented “operators<” or “operator>” in the BaseCluster class are not touched at all. The operators are public and look like this.
bool operator< (const BaseCluster * rhs) const {
return m_score < rhs->m_score;
}
bool operator> (const BaseCluster * rhs) const {
return m_score > rhs->m_score;
}
2.) Using a predicate / functor
class BaseClusterComparator {
public:
bool operator() (const BaseCluster * a, const BaseCluster * b) const {
wcout << "BaseClusterComparator" << endl;
wcout << a->getScore() << " <> " << b->getScore() << endl;
if (a->getScore() > b->getScore()) {
return -1;
} else if (a->getScore() < b->getScore()) {
return 1;
} else {
return 0;
}
}
};
the class member getScore looks like this
float
BaseCluster::getScore() const {
return m_score;
}
and executing the sort with
sort(baseClusters.begin(), baseClusters.end()), BaseClusterComparator());
will result in an segmentation fault when trying to access the getScore() method after sorting about 60 – 70 objects.
Program received signal SIGSEGV, Segmentation fault.
0x00000000004773ec in BaseCluster::getScore (this=0x2ef1) at algorithm/BaseCluster.cpp:44
44 return m_score;
I have the feeling that due to reserving / resizing of the vector there are NULL-objects (constructed with the default constructor of BaseClass ?!).
And now am stuck on how to solve the problem. What am I doing wrong here? I been reading through many other related stackoverflow questions before asking here, followed them by changing here and there but no way out of the seg. faults. As far as I am aware I do not insert any Null-Objects (tested that in the loop), so there must be another flaw in my code. Thought it was an quiet easy task changing to a vector of pointers, but seems more complicated now…
Please, anybody help me on this issue. Thanks so much in advance!
Your comparator is wrong:
std::sortis not like qsort in the comparator. You just have to return the same as the less than operator. For example