C ++ Отладка "Запаха" - PullRequest
       46

C ++ Отладка "Запаха"

0 голосов
/ 28 марта 2011

Я отлаживал странную проблему, когда объекты VMT внезапно указывали на методы базового объекта.

class Base
{ 
  virtual void foo() {}
}

class Derived: public Base
{ 
  void foo() {}
}

Derived * d =  new Derived;

... much complex fettling ...

d->foo(); // Help! called Base::foo()!!!

Оказалось, что ошибка в «сложном» коде эффективно приводила к delete d;. Я не буду вдаваться в подробности, кроме как скажу, что boost::noncopyable - ваш друг, и никогда ни при каких обстоятельствах не катайте свои собственные классы умных указателей.

Но, мой вопрос заключается в следующем: является ли такое изменение VMT хорошим «запахом», который вы имеете дело с удаленным объектом? Я предполагаю, что VMT "развернут" обратно к Base во время уничтожения?

Очевидно, это ужасно зависит от имплментации, и мне повезло, что память не была растоптана ...

Ответы [ 3 ]

4 голосов
/ 28 марта 2011

Не уверен, что вопрос, но я бы сказал, что это:

Мне повезло, что память не растоптала ...

не так: вам не повезло - вам или повезло. Если бы при удалении была растоптана память, возможно, сбой кода был бы намного ближе к реальной проблеме, и ошибка была бы намного яснее.

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

1 голос
/ 28 марта 2011

Я могу говорить только за g ++, для которого наблюдаемое вами изменение vtable на самом деле и происходит.Иногда вы можете использовать это, чтобы определить, что объект указателя был удален, но это обычно не очень помогает, так как удаление может происходить в более чем одном месте.shared_ptr и unique_ptr ваши друзья для управления памятью.

0 голосов
/ 28 марта 2011

Вам повезло, что вы получили поведение базового класса, а не сегфо.

Если вы гадите с удаленным объектом, поведение не определено.

...