C99:是否可以设计一个没有动态分配的抽象数据类型?

C99: is it possible to design an abstract datatype without dynamic allocation?

我必须设计一个抽象数据类型,但不允许我使用动态分配。似乎有点棘手...

我目前拥有的:

在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( ... ) 时(例如全局),我收到一条错误消息。

有没有可能改进这个?目前,我唯一的选择是将数据类型设置为 public...

TIA 为你的想法!

您的方法根本行不通,因为一旦您开始将 uint8_t 缓冲区用于不相关的目的,您就违反了严格的别名。事实上,这就是您在这里所做的:struct adt* NAME = (adt*) & NAME ## _storage;。那是未定义的行为。

通常,通过在 ADT 中创建您自己的内存池来解决无法访问 malloc(如您的普通嵌入式系统)的问题。内存池是不透明结构类型的 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 最有意义。对于更简单的结构,所需的开销可能不值得,在这种情况下,您应该考虑制作整个结构 public。

还有其他方法,我强烈建议阅读所有 Static allocation of opaque data types。很多不错的提示和技巧。