AUTOSAR C++14 Rule A3-8-1
An object shall not be accessed outside of its lifetime
説明
ルール定義
An object shall not be accessed outside of its lifetime.
根拠
オブジェクトの有効期間は、それがそのコンストラクターによって作成された時点から始まります。この有効期間は、オブジェクトが削除された時点で終わります。コンストラクターの前またはデストラクターの後に変数にアクセスすると、未定義動作につながる可能性があります。状況によっては、多数の操作が有効期間外のオブジェクトに誤ってアクセスする可能性があります。このような操作の例を以下に示します。
未初期化ポインター:アドレスを割り当てる前のポインターに誤ってアクセスしてしまう場合があるかもしれません。この操作では、有効期間内のオブジェクトにアクセスした結果、予測不能なメモリ位置にアクセスすることになります。ベスト プラクティスは、宣言中に
nullptrを使用してポインターを初期化することです。未初期化変数:初期化する前の変数を誤って読み取ってしまう場合があるかもしれません。この操作では、有効期間内のオブジェクトにアクセスした結果、予測不能で役に立たないゴミ値を読み取ることになります。ベスト プラクティスは、宣言中に変数を初期化することです。
既に割り当て解除されたポインターの使用:メモリの割り当て解除後に、ポインターの動的に割り当てられたメモリにアクセスしてしまう場合があるかもしれません。メモリのこのブロックにアクセスしようとすると、有効期間後のオブジェクトにアクセスすることになり、予測不能な動作やセグメンテーション違反すら発生する可能性があります。この問題を解決するには、割り当て解除されたポインターを
nullptrに設定してから、アクセスする前にポインターがnullptrかどうかをチェックします。または、生のポインターの代わりにstd::unique_ptrを使用します。std::unique_ptr用に割り当てられたメモリは明示的に割り当て解除する必要がないため、割り当て解除されたメモリに誤ってアクセスすることがなくなります。スコープ外のスタック変数へのポインターまたは参照:非ローカル ポインターをローカル オブジェクトに割り当てる場合があるかもしれません。次に例を示します。
非ローカル ポインターまたはグローバル ポインターが、関数に対してローカルな変数に割り当てられる。
ポインターなどの参照渡し関数パラメーターが、関数に対してローカルな変数に割り当てられる。
クラスのポインター データ メンバーが、関数に対してローカルな変数に割り当てられる。
ローカル変数がスコープ外になると、それに対応するメモリ ブロックにゴミ値や予測不能値が格納される可能性があります。このようなメモリ位置へのポインターにアクセスすると、有効期間外のオブジェクトにアクセスすることになり、未定義動作や予測不能動作につながる可能性があります。ベスト プラクティスは、非ローカル ポインターをローカル オブジェクトに割り当てないようにすることです。
有効期間が一時的なオブジェクトの変更:関数呼び出しから返された一時オブジェクトを変更しようとする場合があるかもしれません。一時オブジェクトの変更は、使用しているハードウェアとソフトウェアによってはプログラムの異常終了につながる未定義動作です。ベスト プラクティスは、ローカル変数に一時オブジェクトを割り当ててから、そのローカル変数を変更することです。
有効期間外のオブジェクトにアクセスする可能性のある操作は避けてください。
Polyspace 実装
Polyspace® は、有効期間外のオブジェクトがアクセスされる可能性のある次のようなシナリオをチェックします。
未初期化ポインター: Polyspace は、アクセスする前にアドレスが割り当てられていないポインターにフラグを設定します。
未初期化変数: Polyspace は、値が読み取られる前に初期化されていない変数にフラグを設定します。
既に割り当て解除されたポインターの使用: Polyspace は、たとえば関数
free()やdelete演算子を使用してブロックの割り当てを解除した後、そのメモリ ブロックにアクセスする操作にフラグを設定します。スコープ外のスタック変数へのポインターまたは参照: Polyspace は、ポインターまたは参照がスコープ外のローカル変数にフラグを設定します。たとえば、以下の場合にローカル変数にフラグが設定されます。
関数がローカル変数へのポインターを返す
グローバル ポインターがローカル変数を指している
ポインターなどの参照渡し関数パラメーターがローカル変数を指している
クラスのポインター データ メンバーがローカル変数を指している
Polyspace は、関数定義に含まれるローカル オブジェクトは同じスコープ内にあると仮定します。
有効期間が一時的なオブジェクトへのアクセス: Polyspace は、関数呼び出しから返された一時オブジェクトにアクセスする操作にフラグを設定します。
チェッカーの拡張
チェッカーは次の方法で拡張できます。
Polyspace は、関数に未初期化変数を渡すポインターにフラグを設定しません。ポインターによって関数に渡される、初期化されていない変数を検出するには、オプション
-code-behavior-specificationを使用してチェッカーを拡張します。関数引数のポインター渡しをチェックする初期化のためのチェッカーの拡張を参照してください。特定のシステム入力値の場合にのみ、コード内のある変数が初期化されない場合は、欠陥を引き起こす可能性のある入力値の組み合わせの 1 つと見なすことができます。特定のシステム入力値から欠陥を見つけるための Bug Finder チェッカーの拡張を参照してください。
トラブルシューティング
ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。
例
チェック情報
| グループ: 基本概念 |
| カテゴリ: Required、Non-automated |