抽象データ型を設計する必要がありますが、動的割り当てを使用することは許可されていません。少しトリッキーなようです...
私が現在持っているもの:
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 );
}
プロ側では、不透明(OPAQUE)型を使用しているため、動的割り当てを使用する必要はありません。
反対に、これは醜いです。また、関数内からではなく(グローバルになど)ADT_DATA(...)を呼び出そうとすると、エラーメッセージが表示されます。
これを改善することは可能ですか?現在、私の唯一の選択肢は、データ型を公開することです...
あなたのアイデアのためのTIA!
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に最も適しています。より単純なものの場合、必要なオーバーヘッドはそれだけの価値がない可能性があり、そのような場合は構造体全体を公開することを検討する必要があります。
他の方法もありますが、不透明(OPAQUE)型の静的割り当てをすべて読むことを強くお勧めします。素敵なヒントとコツがたくさん。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加