Анализатор обнаружил, что для работы с объектом класса используются такие низкоуровневые функции, как 'memset', 'memcpy', 'memmove', 'memcmp', 'memchr'. Это недопустимо, если класс содержит указатель на таблицу виртуальных функций (vtable).
Если указатель на объект передается в качестве целевого функциям 'memset', 'memcpy' или 'memmove', то они могут испортить vtable. Если указатель передается в качестве источника функциям 'memcpy' или 'memmove', то результат такого копирования может быть непредсказуемым. В случае с функциями 'memcmp' и 'memchr' сравнение или поиск при наличии vtable также может привести к нежелательному результату.
Рассмотрим пример кода:
class MyClass { public: MyClass(); virtual ~MyClass(); private: int A, B, C; char buf[100]; }; MyClass::MyClass() { memset(this, 0, sizeof(*this)); }
Обратите внимание, что в классе есть виртуальный деструктор. Это значит, что в классе присутствует vtable. Программист поленился очищать члены класса по отдельности. Для очистки он использовал функцию 'memset'. Это привет к порче vtable, так как функция 'memset' ничего про него не знает.
Корректный код:
MyClass::MyClass() : A(0), B(0), C(0) { memset(buf, 0, sizeof(buf)); }
Начиная с C++11, можно переписать этот код следующим образом, если требуется инициализировать поля нулями:
class MyClass { public: MyClass() = default; virtual ~MyClass() = default; private: int A = {}, B = {}, C = {}; char buf[100] = {}; };
Данная диагностика классифицируется как:
|
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V598. |