3

この質問は、MISRAC:2012 ガイドラインに従った ISO C99 でのコーディングに関するものです。

Dir 4.8「If a pointer to a structure or union is never dereferenced within a translation unit, then the implementation of the object should be hidden」と Dir 4.12「動的メモリ割り当てを使用してはならない」に関するガイダンスを探しています。

C で抽象データ型を実装する場合、ADT の内部状態を記述する構造体へのポインタであるハンドルを使用して ADT を参照するのが一般的です。これは、Dir 4.8 に従って不透明なポインターを使用して行うことができ、内部の詳細がユーザーから隠されているという利点があります。

通常、これらの ADT は複数存在する可能性があるため、複数のハンドルを作成する方法が必要です。これは、初期化関数でハンドルによって参照される内部詳細にメモリを割り当てることで解決できますが、これは Dir 4.12 では許可されていません。

もう 1 つのオプションは、初期化ルーチンがユーザーによって提供された静的に割り当てられたハンドルへのポインターを受け取ることですが、これは不透明なポインターを使用して行うことはできません。

以下に問題を示します。

    Module.h 

    struct module; 
    typedef struct module module_t; /* Module handle is only available to  the world as an incomplete type. This allows us to satisfy MISRAC 2012 Dir 4.8.*/

    Module.c

    #include "module.h"
    struct module
    {
        uint8_t value;
    };
    module_t* module_get_a_handle(void)
    {
         return (module_t*)malloc(sizeof(struct module)); /* MISRAC 2012 Dir 4.12 disallows dynamic memory allocation.*/
    }

    User.c

    #include "module.h"
    module_t* module_handle;
    module_handle = module_get_a_handle();

この問題は、この質問 Static allocation of opaque data typesでも​​説明されていますが、MISRAC:2012 ガイドラインに関しては説明されていません。

説明されている 1 つの解決策は、クライアント コードで使用できるハンドルの静的に割り当てられたプールを使用することです。このソリューションは技術的に準拠しているようです。ただし、ここでは動的メモリ割り当ての概念がまだ存在しているようです。ハンドルは静的に割り当てられますが、ソフトウェアが正しく機能するのに十分なハンドルが使用可能かどうかは、コンパイル中にコンパイラーによって判断できないと私は主張します。

この問題に対する私の解決策は、Dir 4.8 に関する逸脱を記述し、不透明でないポインターと、ADT の内部の詳細を変更してはならないことをユーザーに明確にする強力な命名規則を使用することです。

Dir 4.8 および Dir 4.12 を満たし、他の MISRAC:2012 ルールに違反しない、この問題を解決するための広く受け入れられている方法があるかどうかに興味があります。どんなコメントでも大歓迎です。

4

1 に答える 1

1

問題と解決策の両方を理解しているようです。各 ADT 内から静的メモリ プールを使用します。

ただし、このプールは特定の最大制限に制限する必要があり、ハードコーディングする必要があります。基本的にstatic、ファイル スコープでプールをバッファーとして実装し、カウンター変数を使用して "割り当てられた" サイズを追跡します。追加するアイテムごとに、最大制限に対するカウンターをチェックします。

スペースが不足した場合、プログラムはそれを認識し、そのエラーを安全な方法で処理できます。ただし、スペースが不足する理由があってはなりません。これは、設計上のバグがあることを意味します。コンパイル時にスペースが不足しないことをほぼ確実に確認できるはずです。そうでない場合は、少なくともコード カバレッジ テスト中です。


ディレクティブ 4.12 は、malloc/free. これらの関数とヒープを使用することは、動的メモリ割り当てという用語の C の事実上の標準的な定義です。それ以外の意味はありません。

動的割り当てには複数の問題があります。非決定的な割り当て時間、セグメンテーション、メモリ リークなどです。

プログラムの動作が決定論的である限り、「動的性」自体は問題ではありません。安全基準は、ヒープ上の動的メモリ割り当てに常に関心を持っています。これは、安全性が重要なソフトウェア設計における重大な罪である非決定論的な動作を意味するためです。

ベアメタル/RTOS マイクロコントローラ アプリケーションなどの多くの一般的な組み込みシステムでは、動的割り当てはまったく意味がありません


したがって、静的メモリ プールは「動的メモリ割り当て」ではありません。そうしないと、スタックの使用が「動的メモリ」としてカウントされすぎて、有用なソフトウェアをまったく作成できなくなります。

于 2016-02-11T15:00:33.830 に答える