メインコンテンツ

CERT C: Rule ARR36-C

同じ配列を参照しない 2 つのポインターを減算したり比較したりしない

説明

ルール定義

同じ配列を参照しない 2 つのポインターを減算したり比較したりしないようにします。1

Polyspace 実装

ルール チェッカーは、"異なる配列を指すポインター間の減算または比較" をチェックします。

すべて展開する

問題

異なる配列を指すポインター間の減算または比較は、null ポインターまたは異なる配列の要素を指すポインターを減算または比較する場合に発生します。比較の関係演算子は ><>=、および <= です。

リスク

同じ配列内の要素を指す 2 つのポインターを減算する場合、結果は 2 つの配列要素の添字の間の差になります。同様に、配列の要素を指す 2 つのポインターを比較する場合、結果は相対的なポインターの位置になります。ポインターが null または異なる配列の要素を指している場合、減算や比較演算は未定義です。減算結果をバッファー インデックスとして使用する場合、バッファー オーバーフローが発生する可能性があります。

修正方法

配列要素を指すポインターの減算や比較演算子による比較を行う前に、ポインターが非 null であり同じ配列を指していることをチェックします。

例 - 異なる配列内の要素を指すポインター間の減算
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE20 20

size_t func(void)
{
    int nums[SIZE20];
    int end;
    int *next_num_ptr = nums;
    size_t free_elements;
	/* Increment next_num_ptr as array fills */
	
	/* Subtraction operation is undefined unless array nums 
	is adjacent to variable end in memory. */
    free_elements = &end - next_num_ptr;  //Noncompliant
    return free_elements;
}
    
      

この例では、配列 nums がインクリメントされて埋めらます。その後、空の要素がいくつ残っているか判断するためにポインターの減算が使用されます。endnums の最後の要素を超えたメモリ位置を指していない限り、減算演算は未定義です。

修正 — 同じ配列を指すポインターを減算

配列の最後の要素を指すポインターから埋められた最後の要素を指すポインターを減算します。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE20 20

size_t func(void)
{
    int nums[SIZE20];
    int *next_num_ptr = nums;
    size_t free_elements;
	/* Increment next_num_ptr as array fills */
	
	/* Subtraction operation involves pointers to the same array. */
    free_elements = &(nums[SIZE20 - 1]) - next_num_ptr;  
	
    return free_elements + 1;
}
     

チェック情報

グループ: Rule 06.配列 (ARR)

バージョン履歴

R2019a で導入

すべて展開する


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.