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

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

Описание

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

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

  • Оператор typeid разыменовывает указатель NULL.

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

  • (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 является красной.

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

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