lapsus alumni

czerwiec 3, 2007

Znajdź błąd #1: Dziedziczenie

Zaszufladkowany do: Programowanie — elmopl @ 7:03 pm

Tak w ramach przygotowań do kolokwium wymyślałem sobie problemy i wyszło mi to co poniżej prezentuję.
Poniższy kod powoduje (a przynajmniej powinien) naruszenie ochrony pamięci:

class A {
 protected:
   char *t;
 public:
   A(int i = 1) : t(new char[i]) {};
   ~A(){ delete [] t; };
};

class B : virtual public A {
 private:
   int m_ElementsCount;
 public:
   B(int elementsCount) : A(elementsCount), m_ElementsCount(elementsCount) {};

   int writeElement(unsigned int i, unsigned int k){
      if(i < m_ElementsCount){
         t[i] = k;
         return 0;
      }
      else return 1;
   };
};

class C : public B{
 public:
   C(int elementsCount) : B(elementsCount) {};
};

int main(int argc, char **argv){
   C myC(100);

   myC.writeElement(99, 2);

   return 0;
}

Żeby go poprawić wystarczy usunąć jeden wyraz (blok funkcji main zostawiamy w spokoju).
Odpowiedź po kliknięciu “więcej”.

Odp: wystarczy usunąć słowo kluczowe virtual z deklaracji dziedziczenia klasy A przez klasę B. Wynika to z tego, iż słowo virtual mianuje klasę dziedziczącą z B odpowiedzialną za wykonanie konstruktora klasy A. Tym samym klasa C wykonuje konstruktor domyślny A(0) (jako, że nie został zdefiniowany żaden konkretny) i w ten sposób klasa B “myśli”, że jest 100 elementów w tablicy A::t, a klasa A zaalokowała tylko jeden.
Biorąc pod uwagę kody jakie czasem mogę przeczytać nie jest to taki zupełnie abstrakcyjny przykład.

Nie ma jeszcze komentarzy »

Brak komentarzy.

Kanał RSS z komentarzami do tego wpisu. Adres TrackBack

Dodaj komentarz

Blog na WordPress.com.