Array Of Objects Having Virtual Functions In C++
Follow the series “C++ By Examples” for all the C++ tutorials.
You must be aware of polymorphism in C++. It is achieved by declaring virtual functions. I won’t go into details of how to do that. But today we’ll see one particular dangerous side effect of polymorphism. I’ll show when you use array of objects having virtual functions might crash. This is due to array subscripts are calculated on the bases of sizeof operation. See below code for illustration of the problem. We have Base class having ctor, dtor and virtual function. The Derived class contains ctor, dtor, overridden virtual function and one integer data member.
I pass array of Derived objects to sample function which takes Base* as argument. When I access the first array object, it will work fine. But when I try to access the second array object, it will crash and generate core dump. Reason being the computing of array subscript. In the sample function, sizeof(Base) will be called which is 4 bytes ( this can be different based on the machine you’re using). But actually the objects are of Derived class. If you call sizeof(Derived), it’s 8 bytes. So naturally our virtual pointer (vptr) will be still somewhere in the middle of first array object when we called second array object. This will crash the program.
One solution to avoid this, is to use vector instead of c++ arrays.
See the below code. You can use Makefile posted earlier in this article.
/**
* File Name : 003_virtual-subscript.cpp
* Functionality : See below
* Copyright (C) 2012 Divyang Patel
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/************************************************************
// This program shows when you use arrays of
// objects with virtual mechanism, it might crash
// In below program, Base has ctor, dtor, and virtual function
// while Derived has ctor, overriden virtual function and
// one int derint_. So there is different in sizeof of both
// the objects. When you pass der object array to fucntion
// sample taking Base*, calling der[1].foo() will crash.
// Because the vptr is still somewhere in middle of der[0]
// due the sizeof
************************************************************/
#include <iostream>
using namespace std;
class Base
{
public:
Base(){}
~Base(){}
virtual void foo(){ cout<< "Base foo()" << endl; }
};
class Derived : public Base
{
public:
Derived():Base(),derint_(11){}
~Derived(){}
void foo(){ cout << "Derived foo()" << endl; }
int derint_;
};
void sample(Base* der)
{
cout << "calling der[0]" << endl;
der[0].foo();
cout << "calling der[1]" << endl;
der[1].foo();
}
int main()
{
Base bObj;
Derived dObj;
cout << "sizeof(bObj) = " << sizeof(bObj) << endl;
cout << "sizeof(dObj) = " << sizeof(dObj) << endl << endl;
Derived der[10];
sample(der);
return 0;
}
Output
$ ./a.out sizeof(bObj) = 4 sizeof(dObj) = 8 calling der[0].foo() Derived foo() calling der[1].foo() Segmentation fault $


















No comments
C++ By Examples | GoosPoos
05.29.2012
[...] Array Of Objects Having Virtual Functions – Using polymorphism with array of objects can cause program crash. Tweet (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })(); [...]
There are no trackbacks to display at this time.