Reputation: 78
I'm getting some nasty segmentation faults through the g++ compiler on the following code. Any ideas on why this would happen and how to fix it would be great.
#include <iostream>
using namespace std;
class Base {
public:
Base() {}
virtual ~Base() {};
virtual int getNum(int) = 0;
};
class Derived: public Base {
public:
Derived() :
Base() {}
~Derived() {}
int getNum(int num) {
return num;
}
};
class Foo {
public:
Foo() {
};
void init() {
Derived n;
*baseId = n;
}
void otherStuff() {
cout << "The num is" << baseId->getNum(14) << baseId->getNum(15) << baseId->getNum(16) << baseId->getNum(15) << endl;
}
Derived* baseId;
};
int main() {
Foo f;
f.init();
f.otherStuff();
return 0;
}
Upvotes: 2
Views: 1458
Reputation: 57575
void init() {
Derived n;
*baseId = n;
}
Apart from what Neil noted, derived n
is local to your init function. It "dies" when you exit the function, so even if you assigned it correctly, it won't work.
What you want is not assigning on the stack but on the heap:
void init() {
baseId = new Derived();
}
or even better:
void init() {
delete baseId;
baseId = new Derived();
}
and a destructor and constructor pair to prevent problems :
Foo() : baseId(0) {};
~Foo() { delete baseId; }
If going for this method, be sure to either block copy constructor and assignment operator, or implement them properly. To implement them however, you'd need to implement copying of Derived too -- or best: use a safe shared_ptr to store the pointer.
Upvotes: 2
Reputation: 95355
When you call f.init()
, the baseId
member of Foo
is not initialised, yet you dereference it in init()
. Are you sure you don't want something more along the lines of:
baseId = new Derived()
Upvotes: 3
Reputation:
Here:
void init() {
Derived n;
*baseId = n;
}
the pointer baseId is never initialised, resulting in undefined behaviour when you dereference it. It might be a good idea to explain what you are trying to do here. If you want to maintain a pointer to a Derived or a Base but which starts off pointing to a derived, you can say:
void init() {
baseId = new Derived;
}
but you will then probably need a copy constructor, an assignment operator and a destructor to manage the pointer.
Also, for several reasons, writing an init() function is not normally a good idea - you are better off doing the work directly in the constructor or its initialisation list.
Upvotes: 7