Muhammad Arfeen
Muhammad Arfeen

Reputation: 41

Base class pointers and segmentation error

The following code compiles but gives segmentation error when I run it.I am using dynamic memory in the main using base class pointer to derived class object and that gives error when runs.

#include <iostream>
using namespace std;

class Base {
public:
  int b;
  int b1;
  Base() : b(0), b1(0) { cout << "Base constructor" << endl; }
  virtual void Input() {
    cout << "Enter number b : ";
    cin >> b >> b1;
    // return *this;
  }
  virtual ~Base() {}
};
class Derived : public Base {
public:
  int d;
  // Constructor
  Derived() : d(0) { cout << "Derived constructor" << endl; }
  void Input() {
    Base::Input();
    cout << "Enter number d : ";
    cin >> d; //>> d1;
    // return *this;
  }
  ~Derived() {}
};

int main() {
  Base *s = new Derived[2];
  // When complexity of data members increases this line causes
  // segmentation fault
  s[1].Input(); // Here the problem

  delete[] s;
}

Upvotes: 2

Views: 231

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311068

If you will execute these statements

std::cout << "sizeof( Base ) = " << sizeof( Base ) << '\n';
std::cout << "sizeof( Derived ) = " << sizeof( Derived ) << '\n';

then you can see the following output

sizeof( Base ) = 16
sizeof( Derived ) = 24

So the sizes of the classes are different.

In this expression

s[1]

there is used the pointer arithmetic. The expression is evaluated like

*( s + 1 )

that in turn can be rewritten like

*reinterpret_cast<Base *>( ( char * )s + sizeof( Base ) )

Because the static type of the pointer s is Base *.

Thus this expression ( char * )s + sizeof( Base ) is not a pointer to the second element of the type Derived because instead of using the subexpression sizeof( Derived ) there is used the subexpression sizeof( Base ).

Upvotes: 2

Daniel Langr
Daniel Langr

Reputation: 23527

You cannot do this:

Base* s = new Derived[2];

s is basically considered as an array of Base instances, while there are instances of Derived stored inside.

You either need to create an array of pointers to Base and populate it with pointers to dynamically created Derived objects (see this question), or, better use a vector:

std::vector<std::unique_ptr<Base>> s;
s.push_back(std::make_unique<Derived>());
s.push_back(std::make_unique<Derived>());

Upvotes: 6

eerorika
eerorika

Reputation: 238411

The standard says (quote from latest draft):

[expr.delete]

... In an array delete expression, if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.

You array-delete through a pointer to base type: The behaviour of your program is undefined.

Upvotes: 2

Related Questions