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。很多不错的提示和技巧。
我必须设计一个抽象数据类型,但不允许我使用动态分配。似乎有点棘手...
我目前拥有的:
在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。很多不错的提示和技巧。