Invalid C++ specific operations

Выполняются определенные недопустимые операции C++

Описание

Эти проверки операций кода С++ определяют, действительны ли операции. Проверки ищут область значений недопустимого поведения:

  • Размер массива не строго положительный.

  • typeid operator dereferences a NULL указатель.

  • dynamic_cast оператор выполняет недопустимое приведение.

  • (C++ 11 и выше) Количество предложений инициализатора массива превышает количество инициализируемых элементов массива.

  • (C++ 11 и выше) Аргумент указателя на новый оператор размещения не указывает на достаточное количество памяти.

Примеры

расширить все

class License {
protected:
  int numberOfUsers;
  char (*userList)[20];
  int *licenseList;
public:
  License(int numberOfLicenses);
  void initializeList();
  char* getUser(int);
  int getLicense(int);
};

License::License(int numberOfLicenses) : numberOfUsers(numberOfLicenses) {
  userList = new char [numberOfUsers][20];
  licenseList = new int [numberOfUsers];
  initializeList();
}

int getNumberOfLicenses();
int getIndexForSearch();

void main() {
  int n = getNumberOfLicenses();
  if(n >= 0 && n <= 100) {
    License myFirm(n);
    int index = getIndexForSearch();
    myFirm.getUser(index);
    myFirm.getLicense(index);
  }
}

В этом примере аргумент n в конструктор License::License подразделяется на две категории:

  • n = 0: Когда new оператор использует этот аргумент, Invalid C++ specific operations привести к ошибке.

  • n > 0: Когда new оператор использует этот аргумент, Invalid C++ specific operations зеленый.

Объединяя две категории аргументов, Invalid C++ specific operations вызывают оранжевую ошибку на new оператор.

Чтобы увидеть эту проблему, включите опцию Consider environment pointers as unsafe (-stubbed-pointers-are-unsafe).

#include <iostream>
#include <typeinfo>
#define PI 3.142

class Shape {
public:
  Shape();
  virtual void setVal(double) = 0;
  virtual double area() = 0;
};

class Circle: public Shape {
  double radius;
public:
  Circle(double radiusVal):Shape() {
    setVal(radiusVal);
  }

  void setVal(double radiusVal) {
     radius = radiusVal;
  }

  double area() {
    return (PI * radius * radius);
  }
};


Shape* getShapePtr();

void main() {
  Shape* shapePtr = getShapePtr();
  double val;

  if(typeid(*shapePtr)==typeid(Circle)) {
    std::cout<<"Enter radius:";
    std::cin>>val;
    shapePtr->setVal(val);
    std::cout<<"Area of circle = "<<shapePtr->area();
  }
  else {
    std::cout<<"Shape is not a circle.";
  }

}

В этом примере Shape* указатель shapePtr возвращается по getShapePtr() функцию можно NULL. Потому что возможно NULL-значенный shapePtr используется с typeid оператор, проверка Invalid C++ specific operations оранжевая.

class Base {
public :
  virtual void func() ;
};

class Derived : public Base  {
};

Base* returnObj(int flag) {
  if(flag==0)
    return new Derived;
  else
    return new Base;
}


int main() {

    Base * ptrBase;
    Derived * ptrDerived;

    ptrBase = returnObj(0) ;
    ptrDerived = dynamic_cast<Derived*>(ptrBase); //Correct dynamic cast
    assert(ptrDerived != 0); //Returned pointer is not null

    ptrBase = returnObj(1);
    ptrDerived = dynamic_cast<Derived*>(ptrBase); //Incorrect dynamic cast
    // Verification continues despite red
    assert(ptrDerived == 0); //Returned pointer is null
}

В этом примере Invalid C++ specific operations на dynamic_cast оператором являются:

  • Зеленый, когда указатель ptrBase который оператор преобразует в Derived уже указывает на Derived объект.

  • Красный, когда указатель ptrBase который оператор преобразует в Derived указывает на Base объект.

    Проверки красного цвета обычно останавливают верификацию в тех же возможностях, что и проверка. Однако после красного Invalid C++ specific operations на dynamic_cast операция с использованием указателей, верификация продолжается. Программное обеспечение принимает, что dynamic_cast оператор возвращает NULL указатель.

class Base {
public :
  virtual void func() ;
};

class Derived : public Base  {
};

Base& returnObj(int flag) {
  if(flag==0)
    return *(new Derived);
  else
    return *(new Base);
}


int main() {
  Base & refBase1 = returnObj(0);
  Derived & refDerived1 = dynamic_cast<Derived&>(refBase1); //Correct dynamic cast;

  Base & refBase2 = returnObj(1);
  Derived & refDerived2 = dynamic_cast<Derived&>(refBase2); //Incorrect dynamic cast
  // Analysis stops
  assert(1);
}

В этом примере Invalid C++ specific operations на dynamic_cast оператором являются:

  • Зеленый, когда ссылка refBase1 который оператор преобразует в Derived& уже ссылается на Derived объект.

  • Красный, когда ссылка refBase2 который оператор преобразует в Derived& ссылается на Base объект.

    После красного Invalid C++ specific operations на dynamic_cast операция с использованием указателей, программное обеспечение не проверяет код в тех же возможностях, что и проверка. Например, программное обеспечение не выполняет проверку User assertion на assert оператор.

#include <stdio.h>

int* arr_const;

void allocate_consts(int size) {
    if(size>1)
      arr_const = new int[size]{0,1,2};
    else if(size==1)
      arr_const = new int[size]{0,1};
    else
       printf("Nonpositive array size!");
}

int main() {
    allocate_consts(3);
    allocate_consts(1);
    return 0;
}

В этом примере проверка Invalid C++ specific operations определяет, совпадает ли количество предложений инициализатора с количеством элементов, которые нужно инициализировать.

При первом вызове allocate_constsСписок инициализации имеет три элемента, чтобы инициализировать массив размера три. Проверка Invalid C++ specific operations на new оператор зеленый. Во втором вызове список инициализации имеет два элемента, но инициализирует массив размера один. Проверка на new оператор красный.

#include <new>

class aClass {
  virtual void func();  
};

void allocateNObjects(unsigned int n) {
    char* location = new char[sizeof(aClass)];
    aClass* objectLocation = new(location) aClass[n];  
}

В этом примере память равна размеру одного aClass объект связан с указателем мыши location. Однако в зависимости от аргумента функции n при использовании размещения может быть выделено несколько объектов new оператор. Указатель location возможно, недостаточно памяти для выделенных объектов.

Проверяйте информацию

Группа: C++
Язык: C++
Акроним: CPP