Вызов деструктора в C ++ - PullRequest
1 голос
/ 22 октября 2011

Я изучал, что Destructor вызывается всякий раз, когда объект выходит из области видимости или когда выделенная ему память освобождается с помощью оператора delete.

#include  <iostream>

using namespace std;

class point
{
   private:
      int x_coord;
      int y_coord;

   public:
      point()
      {
         x_coord = 0;
         y_coord = 0;
      }

      point(int x, int y)
      {
         x_coord = (x > 79 ? 79 : (x < 0 ? 0 : x));
         y_coord = (y > 79 ? 79 : (y < 0 ? 0 : y));
      }

      ~point()
      {
         cout << "Destructor invoked\n";
      }

      int getx(void)
      {
         return x_coord;
      }

      int gety(void)
      {
         return y_coord;
      }
};

int main()
{
   point p1;
   point p2(20, 80);

   point *p3 = new point;

   cout << "p1.x =  " << p1.getx() << ": p1.y = " << p1.gety()<< "\n";
   cout << "p2.x =  " << p2.getx() << ": p2.y = " << p2.gety()<< "\n";
   cout << "p3->x =  " << p3->getx() << ": p3->y = " << p3->gety()<< "\n";

   point * p4 = &p1;
   delete p4;
   delete p3;

   return 0;

}
  1. память, выделенная для p1, выделяется с помощью delete p4.Таким образом, деструктор вызывается
  2. delete p3 вызывает следующий деструктор.
  3. p2 выходит из области видимости, и вызывается следующий деструктор.

Я ожидал, что деструктор будетвызывается только 3 раза.Но я вижу, что деструктор вызывается 4 раза.Что является причиной этого?Есть ли какая-то ошибка в моем понимании деструкторов

Ответы [ 4 ]

4 голосов
/ 22 октября 2011

Вы уничтожаете p1 дважды, один раз, когда p1 выходит из области видимости, но также и когда вы вызываете delete p4, который является просто указателем на p1, а не на отдельный объект.Уничтожение объекта дважды - неопределенное поведение, кстати (как и удаление объекта стека (см. Комментарий)).

4 голосов
/ 22 октября 2011

Ошибка в коде. Вы не можете delete p1 (p4 указывает на p1), так как он не был создан с помощью new. Таким образом, программа вызывает неопределенное поведение.

В данном конкретном случае происходит то, что деструктор p1 вызывается дважды: сначала с delete, во второй раз, когда p1 выходит из области видимости. Это может быть что-то еще (другой вероятный результат - авария).

1 голос
/ 22 октября 2011

p1 было выделено в стеке, поэтому, даже если вы вызвали delete на p4, удаление будет вызвано на нераспределенном p1.

Обратите внимание, что освобождение памяти не 'т (обязательно) обнулить его.Таким образом, деструктор может быть вызван снова и распечатать сообщение.Или это может взорваться.Вот почему важно убедиться, что вы не освобождаете память перед последним использованием.

0 голосов
/ 22 октября 2011

Ваше уничтожение p1 через указатель p4 недопустимо и вызовет ошибку времени выполнения, если вы компилируете с отладочным CRT.

...