Выполняются определенные недопустимые операции C++
Эти проверки операций кода С++ определяют, действительны ли операции. Проверки ищут область значений недопустимого поведения:
Размер массива не строго положительный.
typeid operator dereferences a NULL указатель.
dynamic_cast оператор выполняет недопустимое приведение.
(C++ 11 и выше) Количество предложений инициализатора массива превышает количество инициализируемых элементов массива.
(C++ 11 и выше) Аргумент указателя на новый оператор размещения не указывает на достаточное количество памяти.
Просмотр и исправление недопустимых проверок конкретных операций C++
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 оператор.
typeid Удаление оператора из NULL УказательЧтобы увидеть эту проблему, включите опцию 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 оранжевая.
dynamic_cast по указателям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 указатель.
dynamic_cast On Referencesclass 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 оператор красный.
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 |
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.