C++ определенные недопустимые операции происходит
Они начинают работу, операции Кода С++ определяют, допустимы ли операции. Проверки ищут область значений недопустимых поведений:
Размер массивов не строго положителен.
typeid
оператор разыменовывает 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
на Ссылках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
оператор является красным.
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. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.