-4

I'm trying to understand what is happening with pointers of classes. I made a base class called A and B class which inherits after A. I thought that pointer of Base class can point on any class which inherits after base. But I have a problem with memory here and I don't know why.

#include <iostream>
using namespace std;

class A{
public:
    A(){}

    int zmienna_klasy_A;

    A(int x){
        cout << "Konstruktor klasy A\n";
        zmienna_klasy_A = x;
    }

    virtual ~A(){}
};


class B: public A{
public:
    B(){}
    int zmienna_klasy_A;

    B(int x) : A(20){
        cout << "Konstruktor klasy B\n";
        zmienna_klasy_A = 10000;
        wypisz();
    } 

    ~B(){}

};


int main(){
    A *obiekt_bazowy;
    B *obiekt_pochodny;

    obiekt_bazowy = new B;
    obiekt_bazowy = obiekt_pochodny; // here is problem
    delete obiekt_bazowy;
}

Also, when I don't allocate memory for B but just write:

int main(){
        A *obiekt_bazowy;
        B *obiekt_pochodny;
        obiekt_bazowy = obiekt_pochodny; 
        }

it is okay. What is happening here?

icnm
  • 7
  • 1
  • 4
  • 3
    You forgot to explain your problem. – tkausl Jun 30 '18 at 07:04
  • 2
    In both cases, `obiekt_pochodny` is used without initialization. The behaviors of both cases are undefined. –  Jun 30 '18 at 07:25
  • 1
    Possible duplicate of [(Why) is using an uninitialized variable undefined behavior?](https://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior) –  Jun 30 '18 at 07:29

1 Answers1

1

Let's break down you main function line by line and talk about what it does.

A *obiekt_bazowy;
B *obiekt_pochodny;

Here 2 pointers have been declared, one is A* and the other is B*. Both pointers are unitialized, so they are just pointing at some random memory location.

obiekt_bazowy = new B;

Here a new instance of B is created. It's memory is allocated on the heap, compared to writing for example B b; which would also create an instance of B, but this time on the stack.

Additionally obiekt_bazowy is made to point at this newly created instance of B. As you said a A* can point to a child class just fine, so making an A* point to an instance of B is ok. obiekt_pochodny however is still not pointing at anything. It's still uninitialized.

obiekt_bazowy = obiekt_pochodny; // here is problem

obiekt_bazowy is now made to point at the same thing obiekt_pochodny is pointing too. But since obiekt_pochodny is still uninitialized, obiekt_bazowy is now pointing to the same uninitialized random memory location.

Additionally we no longer have anything that points to the instance of B that we created earlier with new B, so we can no longer retrieve that memory location and we have leaked memory since we will no longer be able to call delete on it.

delete obiekt_bazowy;

obiekt_bazowy was made to point at uninitialized memory, so when we try to delete it here we are telling the program to try to free uninitialized memory. This is undefined behavior. Hopefully the program will crash when we do this, but we could be more unlucky and the program can end up doing anything really. Freeing some other random piece of memory in our program, or launching a rocket to the moon. There's no way to know what could happen.

super
  • 12,335
  • 2
  • 19
  • 29