I'm getting unstable results with my software and wanted to understand why and how I should modify my code to get consistent results. To show this, I prepared a mock sample of the software; below, I have 2 main classes, Mother
and Daughter
; these are my main data structures, and I use Mother
in many other data structures. Hence, it's essentially an abstract class but can not be purely abstract since some of the observables are also directly dependent on it, so I can not write (as far as I know) pure virtual functions in it. Classes are defined as follows;
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
class Mother {
private:
double some_var_;
public:
Mother() {some_var_ = 0.;}
virtual ~Mother() {}
virtual void print() const
{
std::cout << "printing from mother " << some_var_ << std::endl;
}
virtual void setvar(double v) {some_var_ = v;}
virtual const double var() const {return 0.;}
};
class Daughter : public Mother
{
private:
double new_var_;
public:
Daughter() {new_var_ = 0.;}
virtual ~Daughter() {}
void print() const
{
std::cout << "printing from Daughter " << new_var_ << std::endl;
}
void setvar(double v) {new_var_=v;}
const double var() const {return new_var_;}
};
I interact with these data structures through a collection
class defined as follows;
class collection
{
private:
std::vector<Daughter> daughters_;
public:
collection () {Reset();}
virtual ~collection() {}
void Reset() {daughters_.clear();}
Daughter* GetNewDaughter()
{
daughters_.push_back(Daughter());
return &daughters_.back();
}
const std::vector<Daughter>& daughters() {return daughters_;}
};
Given these, I defined a filter
function to trim these data structures;
template <class T, typename FN>
std::vector<const T*> filter(std::vector<T> objects, FN func)
{
std::vector<const T*> filtered;
for (auto &obj: objects)
{
if (func(&obj)) filtered.push_back(&obj);
}
return filtered;
}
And the code body is as follows;
int main(int argc, char** argv)
{
collection* col = new collection();
for (unsigned int i=0; i<5; i++)
{
Daughter* current = col->GetNewDaughter();
current->setvar(double(i)*2.);
}
std::vector<const Daughter*> filt1 = filter(col->daughters(),
[] (const Daughter* d) {return d->var() > 2.;});
std::vector<const Daughter*> filt2;
for (unsigned int i=0; i<col->daughters().size(); i++)
{
const Daughter * current = &(col->daughters())[i];
if (current->var() > 2.) filt2.push_back(current);
}
std::cout << "first filtered" << std::endl;
for (const Daughter * c: filt1) c->print();
std::cout << "second filtered" << std::endl;
for (const Daughter * c: filt2) c->print();
return 0;
}
As you can see, I defined two filters, one with the filter
function and the other manually, which I expect to see the same result. However, I run the code 4 times, and each time, I got different results;
g++ -Wall -std=c++11 -O3 -fPIC main.cpp -o main
$ ./main
first filtered
printing from Daughter 4
printing from Daughter -2.68156e+154
Segmentation fault: 11
$ ./main
first filtered
printing from Daughter 4
printing from Daughter 0
Segmentation fault: 11
$ ./main
first filtered
printing from Daughter 4
printing from Daughter 2.31584e+77
Segmentation fault: 11
$ ./main
first filtered
printing from Daughter 4
printing from Daughter 6
printing from Daughter 8
second filtered
printing from Daughter 4
printing from Daughter 6
printing from Daughter 8
As you can see, the first 3 runs are completely rubbish for some reason, and the last one is as expected, but it seems to be completely random, so I believe I'm doing something wrong during the memory allocation. I would appreciate it if someone can show me what and why I am doing wrong and how should I change the code to avoid such instability.
Thanks!
Aucun commentaire:
Enregistrer un commentaire