c++ - Segfault when calling virtual function of derived class -
i've been having problem segfaults when call virtual function of derived class. however, these segfaults not occur if change name of function different name of virtual function in base class. here's code:
//in main //initialize scene objects //camera if((camera = (camera*)malloc(sizeof(camera))) == null){ cout << "could not allocate memory camera" << endl; } //...code in middle //inside file parsing... //infile ifstream //nextstring char* if(!strcmp(nextstring,"camera")){ camera->parse(infile); //segfault here }
here base class header (the .cpp instantiates variables in constructor):
class worldobj{ public: worldobj(); ~worldobj(); virtual void parse(ifstream&) =0; vec3 loc; //location };
and here code inside camera class use write virtual function:
void camera::parse(ifstream &infile){ //do parsing stuff }
parse() declared in header file virtual void parse(ifstream&);
my problem here if rename parse() inside camera cameraparse() , ignore fact there virtual function implemented, code works fine!
could shed light on why calling virtual function causes segfault? i've checked valgrind see if there memory issues, , tells me there's invalid read/write of 8 bytes. understand means haven't allocated memory objects, don't know i'm going wrong allocation.
any appreciated :)
you can't (just) malloc
non-pod object, have new
it.
this because malloc
reserves right amount of space, doesn't construct object, non-trivial class virtual functions if constructor defaulted.
now, specific issue arises here when make virtual function call, because depends on initialization carried out new
, it's still wrong use un-constructed instance of non-pod type.
note i'm using pod (plain old data) lazy shorthand trivial initialization. in general, class (or struct) trivially initializable if neither it, nor of members or base classes have constructor does something. our purposes, every class 1 or more virtual methods (even if they're inherited, or in data member) requires non-trivial initialization.
specifically, standard quote in ben voigt's answer describes 2 stages beginning lifetime of object (the time during can safely make method calls, virtual ones):
- storage proper alignment , size type t obtained,
which happens when call malloc
- if object has non-trivial initialization, initialization complete
which only happens non-trivially-initialized type when use new
.
for reference, normal use closest existing code:
camera *camera = new camera; // don't need check null, throw std::bad_alloc if fails camera->parse(file); // don't forget to: delete camera;
this better style, though:
std::unique_ptr<camera> camera(new camera); camera->parse(file); // destruction handled
and if really need use malloc
or other specific allocator:
camera *camera = (camera *)malloc(sizeof(*camera)); new (camera) camera; // turn pointer real object camera->parse(file); // destruction becomes uglier though camera->~camera(); free(camera);
Comments
Post a Comment