このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
無効な 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)