pure virtual method called error - c++

I have the following definitions:
class PartitioningMethod {
public:
virtual void addConstraints(ConstraintManager& cm) = 0;
virtual bool hasMoreConstraints() = 0;
virtual void setQuery(const Query& q) = 0;
virtual ~PartitioningMethod(){ }
};
class Random : public PartitioningMethod {
private:
vector< ref<Expr> > constraints;
vector< ref<Expr> >::iterator it;
vector< ref<Expr> >::iterator end;
int numConstraints;
RNG theRNG;
public:
void setQuery(const Query& q) {
constraints.clear();
//Set random number
//srand ( unsigned ( time (NULL) ) * theRNG.getInt32() );
srand ( theRNG.getInt32() );
//Copy constraints
copy(q.constraints.begin(),q.constraints.end(),std::back_inserter(constraints));
//Shuffle Randomly
std::random_shuffle(constraints.begin(),constraints.end(), p_myrandom);
it = constraints.begin();
end = constraints.end();
numConstraints = constraints.size();
}
void addConstraints(ConstraintManager& cm) {
int step = rand() % numConstraints + 1;
while(step != 0) {
cm.addConstraint(*it);
++it;
--step;
--numConstraints;
}
}
bool hasMoreConstraints() {
return it != end;
}
};
bool PartitioningSolver::computeInitialValues(const Query& query,
const std::vector<const Array*> &objects,
std::vector< std::vector<unsigned char> > &values,
bool &hasSolution) {
fprintf(stderr,"INIT\n");
// If there are no constraints in the query
if(query.constraints.size() == 0 || query.constraints.size() == 1)
return solver->impl->computeInitialValues(query, objects, values, hasSolution);
// If the number constraints in the query are > 0
method->setQuery(query);
ConstraintManager cm;
ref<Expr> expr = query.expr;
fprintf(stderr,"Begin partitioning\n");
fprintf(stderr,"---------------------\n");
while(method->hasMoreConstraints()){
fprintf(stderr, "HERE");
//Add Constraints
method->addConstraints(cm);
//Construct a query
Query temp_query(cm,expr);
ExprPPrinter::printQuery(std::cerr,temp_query.constraints,temp_query.expr);
fprintf(stderr,"---------------------\n");
//Query STP to check if satisfiable
values.clear();
if(!solver->impl->computeInitialValues(temp_query, objects, values, hasSolution))
return false;
//If not, return immediately (a win!)
if(!hasSolution)
return true;
//If a solution is returned, check if the solution satisfies the entire set of constraints
vector<const Array*> obj = objects;
Assignment solution(obj, values);
bool satisfiesAll = checkSolution(solution, query.constraints);
// fprintf(stderr,"Satisfies all: %i\n", satisfiesAll);
// If it is successful, return the solution (a win again!),
if(satisfiesAll)
return true;
// If not add more constraints (if there is more) and repeat
}
return true;
}
A Partial definition for the Partitioning solver class:
class PartitioningSolver : public SolverImpl {
private:
Solver* solver;
PartitioningMethod* method;
bool checkSolution(Assignment& solution, const ConstraintManager& constraints);
public:
PartitioningSolver(Solver *s, PartitioningMethod* pm) : solver(s), method(pm) { }
~PartitioningSolver() { delete solver; delete method; }
};
Sorry for pasting such a long snippet of code but I have been working on it for hours and keep getting the eror
pure virtual method called
terminate called without an active exception
I am not sure what's wrong. It seems to fail in computeInitialValues function where fprintf(stderr,"Begin partitioning\n"); is located. I tried adding print statements as a last resort but even they don't print anything.. Any ideas is appreciated.
EDIT:
Ok so I changed the name Random to Ran and it started to work. I was creating this class instance on the fly as an argument with new Random() I guess it was mixing up with another constructor or something else I dont know..

There's another type of bug, which can cause this error message to be printed.
You deleted the object, and later you're trying to make a call on it. It's undefined behaviour, and on some compilers, if you're lucky, that's what you'll see. Try to run your code with valgrind.
http://tombarta.wordpress.com/2008/07/10/gcc-pure-virtual-method-called/

You're calling a pure virtual function from a constructor in some code that you haven't included for us to see.
When my base class's constructor calls a virtual function on its this object, why doesn't my derived class's override of that virtual function get invoked?

Related

Simple constant getter is creating a cache miss? (C++)

I am currently benchmarking a program on a Linux system with Valgrind.
I have this strange cache miss with the getter method const int GetID() const,
but I can't really explain where it came from. Does anyone have any idea what's causing this problem?
I thought it might be caused by the constant keyword at the end, but it hasn't changed.
The cache miss occurs in the L1 during the read operation. I have added a screenshot below the code snippet.
class GameObject
{
friend class GameManager;
private:
int id;
GameObject();
static int CreateID() { return /* do some id stuff in here */}
...
public:
~GameObject();
const int GetID() const { return id; }
...
};
KCachegrind Screenshot:
UPDATE:
These are methods of the GameManager class that call the const int GetID() const method. It is called when a GameObject must be destroyed or returned to a specific point. The GameManager contains a vector of all GameObjects, they are created when the application starts, after which the vector does not change at all.
After they are created, the attached components call the GameObject* GetGameObject(int const _gameObjectId) method once to retrieve all required components. So I guess the GameObjects should already be in the cache or did I miss a point?
Maybe the call is so strong that it creates more cache misses at the beginning of the program than the rest of the application at runtime?
void GameManager::DestroyGameObject(const int _id)
{
for (auto it = gameObjects.begin(); it != gameObjects.end(); it++)
{
if (it->GetID() == _id)
{
gameObjects.erase(it);
return;
}
}
}
GameObject* GameManager::GetGameObject(const int _gameObjectId)
{
for (int i = 0; i < gameObjects.size(); i++)
{
if (gameObjects[i].GetID() == _gameObjectId)
{
return &gameObjects[i];
}
}
return nullptr;
}

Correctly set return of a function between base and derived class

I have a problem with the following task. I have two classes Config(base) and Ising(derived) each of which has a std::array of 12 bool. I created a function Incr() which does the following
-if the i-th elem of the array is false Incr() sets it as true and exit;
-if the i-th elem of the array is true sets it as false and then moves to the i+1-th elem.
Incr() must work if I call it twice (as in foo.Incr().Incr()) so I thought it should return a reference to a Config
I am now required (it is an exercise )to create an std::vector of 4096 Ising object all created via application of Incr() to the preceding Ising object. Fact is that this function returns a Config...
I can set it to return a Ising but this seems a very poor design choice to have a base class method which returns an object of its derived class.
I was wondering whether there is a more elegant way to do this
This is what I am working with:
class Config {
public:
//ctor
Config(){
for(auto i=m_arr.begin(); i !=m_arr.end(); i++){
*i = false;
}
};
//incr function
Config& Incr(){
for(auto i = m_arr.begin(); i != m_arr.end(); i++){
if(*i ==false){*i = true; return *this;}
else{
*i=false;
}
}
return *this;
};
private:
std::array<bool,12> m_arr;
};
class Ising: public Config{
public:
Ising(double g =1): m_g(g){
};
private:
double m_g;
};
int main(){
Config f; //check ctor
Ising is(3);
is.Incr();
std::vector<Ising> vec;
vec.push_back(is);
for(int i=0; i < 4096; i++){
vec.push_back(vec[i].Incr());
}
return 0;
}
Thanks to everyone who will help
What's wrong with this? No need for a redesign.
Ising is(3);
is.Incr();
std::vector<Ising> vec;
vec.push_back(is);
for (int i = 0; i < 4096; i++) {
vec[i].Incr();
vec.push_back(vec[i]);
}

Sorting a vector of a class

I have class called "UltrasoundTemplate". These UltrasoundTemplate objects contain an int parameter, which shows when they where defined (something like a time stamp). And I have a class called "UltrasoundTarget" which contains a vector of UltrasoundTemplate's.
I add UltrasoundTemplates to the vector with push_back(ultrasoundTemplate).
Now I want to sort the vector by the order of time stamps instead of the order I added them to the vector.
I found a lot of answers in google, which all show me the same solution, but obviously I'm still doing something wrong. Here are the code snippets I think are necessary for finding a solution:
ultrasoundTemplate.h
class UltrasoundTemplate
{
public:
UltrasoundTemplate(/*...*/);
int getVolumePos() { return volume_; }
private:
int volume_;
};
ultrasoundTarget.h
//the sort algorithm
struct MyTemplateSort {
bool operator() ( UltrasoundTemplate t1, UltrasoundTemplate t2){
int it1 = t1.getVolumePos();
int it2 = t2.getVolumePos();
if (it1 < it2)
return true;
return false;
}
};
class UltrasoundTarget
{
public:
UltrasoundTarget(/*...*/);
vector<UltrasoundTemplate> getTemplates() { return USTemplateVector_; }
private:
vector<UltrasoundTemplate> USTemplateVector_;
};
FMainWindow.cpp
void FMainWindow::match_slot()
{
int i;
//here I get the name of the target I'm looking for
QTreeWidgetItem *item = targetInfoWidget_->treeWidget->currentItem();
int index = targetInfoWidget_->treeWidget->indexOfTopLevelItem(item);
QString itemToAppendName = item->text(0);
for(i = 0; i < USTargetVector.size(); i++){
if(USTargetVector.at(i).getName() == itemToAppendName) {
//here I try to sort
MyTemplateSort tmpltSrt;
std::sort(USTargetVector.at(i).getTemplates().begin(),
USTargetVector.at(i).getTemplates().end(), tmpltSrt);
break;
}
}
As an example: I define Template1 in Volume(0), Template2 in Volume(70) and Template3 in Volume(40). The order now is (Template1, Template2, Template3) but I want it to be (Template1, Template3, Template2). But this code is not doing it.
If there's Information missing, just tell me and I'll provide more code.
Thanks alot.
Your getTemplates() method returns by value, making a mess here:
std::sort(USTargetVector.at(i).getTemplates().begin(),
USTargetVector.at(i).getTemplates().end(), tmpltSrt);
You are sorting an incompatible iterator range. You can fix that particular problem by returning a reference:
vector<UltrasoundTemplate>& getTemplates() { return USTemplateVector_; }
It is common practice to add a const overload to such a method:
const vector<UltrasoundTemplate>& getTemplates() const { return USTemplateVector_; }
You can also modify your comparison functor to avoid unnecessary copies (and for general readability and const correctness):
struct MyTemplateSort {
bool operator() const ( const UltrasoundTemplate& t1, const UltrasoundTemplate& t2)
{
return t1.getVolumePos() < t2.getVolumePos();
}
};
This will require that you make getVolumePos() a const method, which it should be anyway:
class UltrasoundTemplate
{
public:
...
int getVolumePos() const { return volume_; }
...
};
Note that is is not generally good practice to provide references to the private data of a class. If possible, you should find a way to remove that from the UltraSoundTarget interface. You could, for instance, expose a pair of iterators, and/or give the class a sort method.
juanchopanza answer is correct, the problem is the way you are returning the vector from UltrasoundTarget. Just to touch another topic, maybe it would be nice to change a little the designing of your implementation. As UltrasoundTarget is a container of Ultrasound's, it makes sense to implement the sort as a method of this class, this way you have direct access to USTemplateVector_ and will save unecessary copies. Something like:
class UltrasoundTarget
{
public:
UltrasoundTarget(/*...*/);
vector<UltrasoundTemplate> getTemplates() { return USTemplateVector_; }
void sort();
private:
vector<UltrasoundTemplate> USTemplateVector_;
};
void UltrasoundTarget::sort()
{
std::sort(USTemplateVector_.begin(), USTemplateVector_.end(), tmpltSrt);
}
void FMainWindow::match_slot()
{
int i;
//here I get the name of the target I'm looking for
QTreeWidgetItem *item = targetInfoWidget_->treeWidget->currentItem();
int index = targetInfoWidget_->treeWidget->indexOfTopLevelItem(item);
QString itemToAppendName = item->text(0);
for(i = 0; i < USTargetVector.size(); i++){
if(USTargetVector.at(i).getName() == itemToAppendName)
{
//here I try to sort
MyTemplateSort tmpltSrt;
USTargetVector.at(i).sort();
break;
}
}

Pointer sets to null-pointer when going out of function

I have quite a blocking problem which I don't understand. Generally, I'm making a kind of anthill simulation. There is one main passage inside divided into segments and from some of the segments ants can enter into chambers. All of these three classes (Passage, Segment, Chamber) have one common thing - collection of ants currently visiting them. So there is an abstract class AntHolder, which contains vector<Ant*> (only members relevant to the case are shown):
class AntHolder
{
protected:
std::vector<Ant*> ants;
/* some other members here */
public:
virtual bool antEnter(Ant* ant) = 0;
/* some other functions here */
};
The antEnter function is implemented differently in derived classes, but generally serves the purpose of adding ant to the ants. From the derived classes particularly I'm interested in AntChamber class (here also less important members were omitted):
class AntChamber : public AntHolder
{
protected:
int itemCapacity;
int additionalCapacity;
std::vector<Item*> items;
bool hasFood;
bool hasEgg;
public:
bool putItem(Item* item);
virtual bool antEnter(Ant* ant);
};
The putItem function is similar to the antEnter function, but it adds Item objects to items collection. (Items are e.g. food, which are moved by ants from one chamber to another.) Below there is shown implementation of both functions:
bool AntChamber::antEnter(Ant* ant)
{
if (items.size() + ants.size() == itemCapacity + additionalCapacity) return false;
ants.push_back(ant);
return true;
}
bool AntChamber::putItem(Item* item)
{
if (items.size() == itemCapacity ||
items.size() + ants.size() == itemCapacity + additionalCapacity)
return false;
if (item->getItemKind() == Food) hasFood = true; // Food == enum value
else if (item->getItemKind() == Egg) hasEgg = true; // Egg == enum value
items.push_back(item);
return true;
}
You can clearly see, that they're almost identical. But when it comes to their effect, there is crucial, surprising difference, and that is the core of my problem.
Let's say I already have an AntChamber* chamber constructed. When I run the following piece of code:
Item* item = new Item(Food);
chamber->putItem(item);
, then after that both item and chamber->items.back() points to some memory with this object. But when I run the analogous piece of code:
Ant* ant = new Ant(chamber);
chamber->antEnter(ant));
, then after that ant point to the object, but chamber->ants.back() points to NULL!
I absolutely can't understand what is going on, especially, that both putItem and antEnter in fact do the same thing: push_back the pointer, which was passed by parameter. I have already tried to simulate such case in some simplier code, like:
class A { };
class B { };
class C
{
vector<A*> va;
vector<B*> vb;
public:
A* vaBack() { return va.back(); }
B* vbBack() { return vb.back(); }
void addA(A* a) { va.push_back(a); }
void addB(B* b) { vb.push_back(b); }
};
int main(int argc, char** argv)
{
A* a = new A();
B* b = new B();
C* c = new C();
cout << (unsigned int)a << endl;
c->addA(a);
cout << (unsigned int)c->vaBack() << endl;
cout << (unsigned int)b << endl;
c->addB(b);
cout << (unsigned int)c->vbBack() << endl;
delete c;
delete b;
delete a;
}
, but it appears to work just fine - none of pointers is 0x000000.
Oh My God, I'm sooo blind...
I did SSCCE, as Shafik Yaghmour advised and I noticed the problem while doing it.
I used a mental leap, saying, that chamber->items.back() or chamber->ants.back() are NULL, because in fact, they weren't! But they're protected in their classes, so I wrote in both classes a function to get to i-th item/ant. The problem was this function. It made a standard idiotproof protection against giving index out of vector's bonds, but made a mistake doing so:
if (idx < 0 || ants.size() >= idx) return 0; // SHOULD BE <= !!!
return ants[idx];
so it always returned 0... And I looked at this method maybe hundreds of times when looking for this problem, and never noticed anything wrong (till now).
Stupid mistake... Thank you very much Shafik.

Inheritance issue

this may be an amateur question, but here it goes. I have three clases:
DrawableObject:
class DrawableObject
{
private:
int x;
//...
public:
int getX();
//...
}
FormElement which inheirts from DrawableObject:
class FormElement : public DrawableObject
FormElement has a method called wasPushed:
bool FormElement::wasPushed(SDL_Event event)
{
bool wasPushed =
(
( event.motion.x >= getX()) //Inherited getX()
&& // Blah blah...
) ? true : false;
return wasPushed;
}
Finally, TextField, which inheirts from FormElement:
class TextField : public DrawableObject
I also have a class, named Form:
class Form {
public:
list<FormElement*> getFormElements();
void generateForm();
private:
list<FormElement*> formElements;
}
Form adds some TextFields to its list, in its generateForm() method:
void Form::generateForm() {
TextField *aTextField = new TextField(10, 10, 120);
this->formElements.push_back(aTextField);
}
Later, it tries to iterate it:
for(list<FormElement*>::iterator it = getFormElements().begin()
; it != getFormElements().end()
; ++it)
{
if ( (*it)->wasPushed(theEvent) )
{ //Etc.
Well, the program exits, when it tries to access getX() from wasPushed method.
Could anyone please tell me why? What am I defining wrong?
I thank you very much.
Martín.
You are returning the list by value:
list<FormElement*> getFormElements();
it should be by reference:
list<FormElement*> &getFormElements();
When you return by value, you are getting a temporary copy of the list.
So in this code:
for(list<FormElement*>::iterator it = getFormElements().begin()
; it != getFormElements().end()
Your begin and end iterators are pointing to two different copies of the list. Also, those temporary copies will be destroyed before you ever have a chance to iterate over them.
You could also use the formElements member directly:
for(list<FormElement*>::iterator it = formElements.begin()
; it != formElements.end()
; ++it)