無効な C++ に固有の演算
C++ 固有の無効演算が発生
説明
C++ コード演算に対するこれらのチェックでは、演算が有効かどうかを判別します。チェックでは、次の一連の無効な動作を探索します。
配列のサイズが厳密に正ではない。
typeid演算子がNULLポインターをデリファレンスする。dynamic_cast演算子が無効なキャストを実行する。(C++11 以降) 配列初期化子句の数が初期化する配列要素の数を超えている。
(C++11 以降) 配置 new 演算子に対するポインター引数が指しているメモリが十分ではない。
このチェックの診断
例
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);
}
}この例では、コンストラクター License::License に対する引数 n は次の 2 つのカテゴリに当てはまります。
n = 0:new演算子がこの引数を使用すると、[無効な C++ に固有の演算] はエラーを生成する。n > 0:new演算子がこの引数を使用すると、[無効な C++ に固有の演算] はグリーンになる。
2 つのカテゴリの引数を結合して、[無効な C++ に固有の演算] は new 演算子でオレンジ エラーを生成します。
この問題を表示するには、オプション環境ポインターが安全でないことを考慮する (-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.";
}
}この例では、関数 getShapePtr() から返される Shape* ポインター shapePtr は NULL の可能性があります。NULL 値の可能性がある shapePtr を typeid 演算子と一緒に使用しているので、[無効な C++ に固有の演算] チェックはオレンジです。
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
}
この例では、dynamic_cast 演算子に対する [無効な C++ に固有の演算] が次のようになります。
演算子が
DerivedにキャストするポインターptrBaseが既にDerivedオブジェクトを指している場合はグリーン。演算子が
DerivedにキャストするポインターptrBaseがBaseオブジェクトを指している場合はレッド。通常、レッド チェックが発生すると、そのチェックと同じスコープの検証は中止されます。ただし、ポインターを含む
dynamic_cast演算に対するレッドの [無効な C++ に固有の演算] の後は検証が続行されます。ソフトウェアでは、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);
}この例では、dynamic_cast 演算子に対する [無効な C++ に固有の演算] が次のようになります。
演算子が
Derived&にキャストする参照refBase1が既にDerivedオブジェクトを参照している場合はグリーン。演算子が
Derived&にキャストする参照refBase2がBaseオブジェクトを参照している場合はレッド。ポインターを含む
dynamic_cast演算に対するレッドの [無効な C++ に固有の演算] の後は、ソフトウェアでそのチェックと同じスコープにあるコードは検証されません。たとえば、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;
}
この例では、[無効な C++ に固有の演算] チェックによって、初期化子句の数と初期化する要素の数が一致しているかどうかを判断します。
allocate_consts の最初の呼び出しでは、サイズが 3 の配列を初期化するために、初期化リストには 3 つの要素があります。new 演算子に対する [無効な C++ に固有の演算] チェックはグリーンです。2 番目の呼び出しでは、初期化リストに 2 つの要素がありますが、初期化する配列のサイズは 1 です。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 |
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)