2

抽象データ型を設計する必要がありますが、動的割り当てを使用できません。少しトリッキーなようです...

私が現在持っているもの:

adt.c で:

struct adt
{
  bool b;
};

const size_t adtSize = sizeof( struct adt );

// Initialisation of the adt
void Adt_New( struct adt* anAdt, bool b )
{
  // No calloc allowed...
  anAdt->b = b;
}

adt.h の見苦しい部分は次のとおりです。

struct adt; // adt structure

extern const size_t adtSize;

// Bear with me...    
#define ADT_DATA( NAME ) uint8_t NAME ## _storage[ adtSize ]; \
    memset( &NAME ## _storage , 0 , adtSize ); \
    struct adt* NAME = (adt*) & NAME ## _storage;

これで、次のように使用できます。

void TestAdt()
{
  ADT_DATA( a );

  Adt_New( a, true );
}

長所として、不透明なデータ型があり、動的割り当てを使用する必要はありません。

反対に、これはただ醜いです。また、関数内からではなく (グローバルに) ADT_DATA( ... ) を呼び出そうとすると、エラー メッセージが表示されます。

これを改善することは可能ですか?現在、私の唯一の選択肢は、データ型を公開することです...

あなたのアイデアのためのTIA!

4

1 に答える 1

3

uint8_tそのバッファを無関係な目的で使用し始めるとすぐに、厳密なエイリアシングに違反するため、このアプローチはまったく機能しません。実際、それはあなたがここでやっていることです: struct adt* NAME = (adt*) & NAME ## _storage;. それは未定義の動作です。

通常、(平均的な組み込みシステムのように) malloc にアクセスできない場合は、ADT 内に独自のメモリ プールを作成することで解決されます。メモリ プールは、不透明な構造体型の X オブジェクトの配列です。不透明なポインターの例を次に示します。

ヘッダー ファイル:

typedef struct adt adt;

C ファイル:

struct adt
{
  // stuff
};


static adt mempool [X];
static size_t mempool_size;    

adt* adt_alloc (/* stuff */)
{
  adt* new_obj;

  new_obj = &mempool[mempool_size];

  mempool_size++;
  if(mempool_size == MAX)
  { /* handle error */ }

  new_obj->this = 123;
  new_obj->that = 456;
  ...

  return new_obj;
}

この方法は、より複雑な ADT に最も適しています。より単純なものの場合、必要なオーバーヘッドはそれだけの価値がない可能性があり、そのような場合は構造体全体を公開することを検討する必要があります。

他の方法も存在します。不透明なデータ型の静的割り当てをすべて読むことを強くお勧めします。素敵なヒントとコツがたくさん。

于 2016-09-30T11:35:53.783 に答える