Defekt? Ale gdzie? 5

Defekt? Ale gdzie? 5
Czy potraficie znaleźć błąd?


Jaki będzie rezultat poniższego kodu?

#include

class X
{
    public:
        int *px;
        X( int init )
            { px = new int; *px = init; }
        ~X() { delete px; }
};

void print( X x )
   {  printf( "%d ", *x.px );  }

int main() {
   X x(15); print( x );
   X y(16); print( x );  print( y );
   return 0;
}




































Odp:
Rezultat to np. 15 16 16. Dlaczego nie spodziewane 15 15 16 ?

Skoro nie został zdefiniowany konstruktor kopiujący dla klasy X, wywołanie funkcji 'print' nie stworzy głębokiej kopii dla obiektu x
(zostanie skopiowany sam wskaźnik zamiast stworzenia duplikatu, czyli alokacji nowej porcji pamięci).
Property px lokalnej kopii obiektu x użytej w czasie wywołania 'print' wskazuje na ten sam int co px obiektu x.
Po wyjściu z funkcji 'print', destruktor niszczy lokalną kopię x, niszcząc też dynamicznie zaalokowany int (px dla x i lokalnej kopii wskazywały na niego).
Teraz px obiektu x wskazuje na niezaalokowaną komórkę pamięci.
W naszym przypadku, po utworzeniu obiektu y, kompilator przydzielił tą zwolnioną pamięć dla y, powodując to że px dla obiektu y i x wskazuje na ten sam int.

To powinno Cię zainteresować