void 类型的数组
普通 C 有一个很好的功能 - void 类型指针,它可以用作任何数据类型的指针。
但是,假设我有以下结构:
struct token {
int type;
void *value;
};
其中值字段可能指向 char 数组、int 或其他内容。
因此,在分配该结构的新实例时,我需要:
1)为此结构分配内存;
2)为值分配内存并将其分配给值字段。
我的问题是 - 有没有方法声明“void类型的数组”,它可以转换为任何其他类型,例如void指针?
我想要的只是使用“灵活的成员数组”(在 C99 标准的 6.7.2.1 中描述),能够转换为任何类型。
像这样:
struct token {
int type;
void value[];
};
struct token *p = malloc(sizeof(struct token) + value_size);
memcpy(p->value, val, value_size);
...
char *ptr = token->value;
我想将 token->value 声明为 char或 int 数组并稍后转换为所需类型将完成这项工作,但对于稍后阅读此代码的人来说可能会非常困惑。
plain C have nice feature - void type pointers, which can be used as pointer to any data type.
But, assume I have following struct:
struct token {
int type;
void *value;
};
where value field may point to char array, or to int, or something else.
So when allocating new instance of this struct, I need:
1) allocate memory for this struct;
2) allocate memory for value and assign it to value field.
My question is - is there ways to declare "array of type void", which can be casted to any another type like void pointer?
All I want is to use "flexible member array" (described in 6.7.2.1 of C99 standard) with ability to casting to any type.
Something like this:
struct token {
int type;
void value[];
};
struct token *p = malloc(sizeof(struct token) + value_size);
memcpy(p->value, val, value_size);
...
char *ptr = token->value;
I suppose declaring token->value as char or int array and casting to needed type later will do this work, but can be very confusing for someone who will read this code later.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
好吧,有点像,但这可能不是您想要的:
以下宏可用于索引您的数据(假设
x
是一个struct token *
):并且,如果如果你喜欢,下面的宏可以包装你的 make_token 函数,使其更直观(或者更黑客,如果你这样想的话):
用法:
Well, sort of, but it's probably not something you want:
The following macro can be used to index your data (assuming
x
is astruct token *
):And, if you like, the following macro can wrap your
make_token
function to make it a little more intuitive (or more hackish, if you think about it that way):Usage:
扩展 AShelly 的答案,你可以这样做;
注意分配内存时使用“offsetof()”而不是“sizeof()”,以避免浪费“void *buf;”字段大小。 “buf”的类型并不重要,但使用“void *”意味着它将针对指针最佳地对齐结构中的“buf”字段,如果需要,可以在其前面添加填充。这通常可以为条目提供更好的内存对齐,特别是当它们至少与指针一样大时。
访问缓冲区中的条目如下所示;
请注意额外的寻址运算符,用于获取“buf”字段的地址作为分配的条目内存的起点。
Expanding on AShelly's answer you can do this;
Note the use of "offsetof()" instead of "sizeof()" when allocating the memory to avoid wasting the "void *buf;" field size. The type of "buf" doesn't matter much, but using "void *" means it will align the "buf" field in the struct optimally for a pointer, adding padding before it if required. This usually gives better memory alignment for the entries, particularly if they are at least as big as a pointer.
Accessing the entries in the buffer looks like this;
Note the extra address-of operator to get the address of the "buf" field as the starting point for the allocated entry memory.
我可能会这样做:
编辑,实际上你必须对这些 p.value[index] = somes 进行类型转换。和/或使用联合来不必进行类型转换。
I would probably do this:
edit, actually you have to typecast those p.value[index] = somethings. And/or use a union to not have to typecast.
你不能有一个“void”项的数组,但你应该能够做你想做的事情,只要你在执行 malloc 时知道 value_size 。但它不会很漂亮。
请注意,当您想要获得额外的存储空间时,您需要一个额外的地址运算符。
这会“浪费” sizeof(void*) 字节,并且
value
的原始类型并不重要,因此您不妨使用较小的项目。我可能会typedef char placeholder;
并将value
设置为该类型。You can't have an array of 'void' items, but you should be able to do something like what you want, as long as you know value_size when you do the malloc. But it won't be pretty.
Note that you need an extra address-of operator when you want to get the extra storage.
This will 'waste' sizeof(void*) bytes, and the original type of
value
doesn't really matter, so you may as well use a smaller item. I'd probablytypedef char placeholder;
and makevalue
that type.以下结构可以帮助您。
更多详细信息: clibutils
following structure can help you.
More Details : clibutils
c/c++ 中不支持void类型的数组。
示例如下:
c/c++ 支持void 指针数组。
下面的例子:
Array of type void is not supporting in c/c++.
Example like:
Array of void pointer is supported in c/c++.
Example below: