標準ライブラリ ルーチンの無効な使用
無効な引数で標準ライブラリ関数が呼び出される
説明
標準ライブラリ関数の呼び出しに対するこのチェックでは、関数が有効な引数によって呼び出されているかどうかを判別します。
このチェックの動作は、メモリ ルーチン、浮動小数点ルーチン、文字列ルーチンのいずれが対象であるかによって異なります。ルーチンによって引数が無効になる状況が異なるためです。各タイプのルーチンの詳細については、以下の例を参照してください。
このチェックの診断
例
#include <assert.h>
#include <math.h>
#define LARGE_EXP 710
enum operation {
ASIN,
ACOS,
TAN,
SQRT,
LOG,
EXP,
};
enum operation getOperation(void);
double getVal(void);
void main() {
enum operation myOperation = getOperation();
double myVal=getVal(), res;
switch(myOperation) {
case ASIN:
assert( myVal <- 1.0 || myVal > 1.0);
res = asin(myVal);
break;
case ACOS:
assert( myVal < -1.0 || myVal > 1.0);
res = acos(myVal);
break;
case SQRT:
assert( myVal < 0.0);
res = sqrt(myVal);
break;
case LOG:
assert(myVal <= 0.0);
res = log(myVal);
break;
case EXP:
assert(myVal > LARGE_EXP);
res = exp(myVal);
break;
}
}この例では、各 assert ステートメントの後、Polyspace® は myVal に assert 条件を true とする値のみが含まれているとみなします。たとえば、assert(myVal < 1.0); の後、Polyspace では myVal には 1.0 より小さい値が含まれるとみなします。
myVal が標準ライブラリ関数で引数として使用されると、その値は関数に対して無効となります。したがって、[標準ライブラリ ルーチンの無効な使用] チェックはレッド エラーを生成します。
浮動小数点ルーチンに対するこのチェックの仕様の詳細については、標準ライブラリの浮動小数点ルーチンの無効な使用を参照してください。
#include <string.h>
#include <stdio.h>
char* Copy_First_Six_Letters(void) {
char str1[10],str2[5];
printf("Enter string:\n");
scanf("%s",str1);
memcpy(str2,str1,6);
return str2;
}
int main(void) {
(void*)Copy_First_Six_Letters();
return 0;
}この例では、文字列 str2 のサイズは 5 ですが、関数 memcpy を使用して 6 文字の文字列 str1 が str2 にコピーされています。したがって、memcpy の呼び出しに対する [標準ライブラリ ルーチンの無効な使用] チェックはレッド エラーを生成します。
他の例については、memset と memcpy に関する Code Prover の仮定を参照してください。
1 つの修正方法として、関数 memcpy でコピーされる文字が収まるように、str2 のサイズを調整するとします。
#include <string.h>
#include <stdio.h>
char* Copy_First_Six_Letters(void) {
char str1[10],str2[6];
printf("Enter string:\n");
scanf("%s",str1);
memcpy(str2,str1,6);
return str2;
}
int main(void) {
(void*)Copy_First_Six_Letters();
return 0;
}#include <stdio.h>
#include <string.h>
char* Copy_String(void)
{
char *res;
char gbuffer[5],text[20]="ABCDEFGHIJKL";
res=strcpy(gbuffer,text);
return(res);
}
int main(void) {
(void*)Copy_String();
}この例では、文字列 text はサイズが gbuffer より大きくなっています。したがって、text を gbuffer にコピーすると、strcpy の呼び出しに対する [標準ライブラリ ルーチンの無効な使用] チェックはレッド エラーを生成します。
1 つの修正方法として、コピー先の文字列 gbuffer をソース文字列 text 以上のサイズで宣言するとします。
#include <stdio.h>
#include <string.h>
char* Copy_String(void)
{
char *res;
char gbuffer[20],text[20]="ABCDEFGHIJKL";
res=strcpy(gbuffer,text);
return(res);
}
int main(void) {
(void*)Copy_String();
}#include <string>
void main() {
std::string str = "";
const char txt[3] = {'n','o','p'};
str.append(txt); //txt is not a valid string
}この例では、txt は null で終了する文字列 (C 文字列) ではありません。したがって、std::string::append の呼び出しに対する [標準ライブラリ ルーチンの無効な使用] チェックはレッドになります。
const char* 引数 を取るメソッドについては、str が NULL ではないこと、また NULL で終了する有効な C 文字列を指していることを確認します。str
#include <string>
void main() {
std::string str = "";
const char txtStr[4] = {'n','o','p', '\0'};
str.append(txtStr); //txtStr is valid string
}関数 free() に対する [標準ライブラリ ルーチンの無効な使用] チェックでは、その関数のポインター引数が以下に当てはまるかどうかを判別します:
非 null のポインターである。
malloc()やrealloc()などの承認済み割り当て関数によって以前に動的に割り当てられている。
このチェックは、以下のようなメモリの解放に関連する問題を検出することができます:
メモリの連続解放。
#include <stdlib.h> #include <stdio.h> int increment_content_of_address(int base_val, int shift) { int j; int* pi = (int*)malloc(sizeof(int)); if (pi == NULL) return 0; *pi = base_val; if(shift < 0) { j = *pi - shift; free(pi); } else if(shift > 0) { j = *pi + shift; free(pi); } else { j = *pi; } free(pi); return j; }この例では、ポインター
piは一部の実行パスで 2 回解放されます。[標準ライブラリ ルーチンの無効な使用] チェックでは、この問題を検出して、潜在的なランタイム エラーを報告します (オレンジ チェック)。動的に割り当てられていないメモリの解放:
#include <stdlib.h> int performOperationsWithAllocatedMemory(unsigned int size) { char base = 0; char *ptr = &base; if(size > 0) { ptr = (char*)malloc(sizeof(char)*size); } //Some operations free(ptr); return 0; }この例では、関数
performOperationsWithAllocatedMemoryの引数sizeがゼロである場合、ポインターptrにメモリが動的に割り当てられません。しかし、引数sizeがゼロである場合を含むすべてのケースで、このポインターに対して関数free()が使用されています。[標準ライブラリ ルーチンの無効な使用] チェックでは、この問題を検出して、潜在的なランタイム エラーを報告します (オレンジ チェック)。
[標準ライブラリ ルーチンの無効な使用] チェックでは、ポインターが外部ポインターであり、その動的メモリ割り当てステータスが不明な場合に、潜在的なランタイム エラーを報告します (オレンジ チェック)。たとえば、ポインター引数をもつ関数がソース ファイルのどこでも呼び出されず、関数本体内で (最初に動的にメモリを割り当てることなく) このポインターに対して free() を使用した場合、free() に対してオレンジ チェックが表示されます。
チェック情報
| グループ: Other |
| 言語: C | C++ |
| 頭字語: STD_LIB |
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)