Invalid C++ specific operations

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

Описание

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

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

  • typeid оператор разыменовывает 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