I overloaded my class’ () operator to use it as a sort comparer function. When using std::sort(), it for some reason calls the the class’ destructor a bunch of times (dependant on the amount of entries in the vector, apparently). I’ve described more in ~RANK().
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
class RANK
{
struct COMBO
{
int x;
};
std::vector<COMBO *> data;
public:
RANK()
{
printf("RANK()\n");
}
~RANK()
{
printf("~RANK()\n");
/*
* Here is the problem.
* Since my vector consists of pointers to COMBO objects,
* I delete them upon RANK object's destruction. However,
* std::sort() calls RANK's destructor many times and
* throws some runtime error, unless commented out.
*/
//for (unsigned int i = 0, n = data.size(); i < n; i++)
// delete data[i];
}
void Add(int x)
{
COMBO *combo = new COMBO();
combo->x = x;
data.push_back(combo);
}
unsigned int Size()
{
return data.size();
}
void Sort()
{
std::sort(data.begin(), data.end(), *this);
}
int operator[](unsigned int pos)
{
return data[pos]->x;
}
bool operator()(COMBO *combo1, COMBO *combo2)
{
return combo1->x > combo2->x;
}
};
int main()
{
RANK rank;
rank.Add(1337);
rank.Add(9001);
rank.Sort();
for (unsigned int i = 0, n = rank.Size(); i < n; i++)
printf("%d ", rank[i]);
printf("\n");
system("pause");
return 0;
}
The output (with commented destructor):
RANK()
~RANK()
~RANK()
~RANK()
~RANK()
~RANK()
9001 1337
The first problem is that you’re breaking the Rule of Three. Your class requires a non-trivial destructor to release its resources, so it needs to be either correctly copyable or uncopyable to avoid multiple objects owning the same resources. The simplest solution is to prevent copying by deleting the copy constructor and copy-assignment operator:
or, if you’re stuck with a pre-2011 compiler, declare them private with no implementation.
Alternatively, you could consider storing smart pointers such as
std::unique_ptr(to prevent copying) orstd::shared_ptr(to allow shared ownership); if you do that, then your class will have the same (safe) copy semantics as the pointer you choose.Preventing copying will make the second problem obvious: you’re using the
RANKobject as the comparator forstd::sort. The comparator is taken by value, so the object is copied there. That’s easy to fix by defining a separate type for the comparator:or, if you can use lambdas: