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. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.