【问题标题】:Random access to members of array of unions随机访问联合数组的成员
【发布时间】:2018-08-29 07:53:05
【问题描述】:

简化示例:

typedef union {
    int foo;
    char* bar;
} int_or_str;

void baz() {
    int_or_str* bogus = malloc(sizeof(int_or_str) * 43);
    bogus[42].bar = "test";
    printf("%s\n", bogus[42].bar);
}
  1. 如果这项工作,编译器会假定bogus 的所有42 个成员都是char 指针吗? (显然,我可以试试这个,但要强调“应该”)。
  2. 它是否定义了当您以这种方式访问​​联合数组时会发生什么?
  3. 假设,我想要一个实际上持有不同大小值的联合数组,这合法吗? (如果我确定联合成员在内存中的布局方式,我可以单独存储布局并计算偏移量)。

如果您想知道这个问题的动机:基本上,我正在尝试为运行时定义的结构提出解决方案。我的想法是有一个联合数组来表示结构字段,以及一些记录如何访问这些字段的元数据。

【问题讨论】:

  • 那应该是int_or_str* bogus = malloc(sizeof(int_or_str) * 43);
  • 这看起来有点像 XY 问题。目前尚不清楚您所说的 3 和最后一段是什么意思。请扩展它们。您的示例在某些情况下“有效”,但我担心您可能会从中得出错误的结论。
  • @PaulOgilvie 已修复,我在这里输入了示例,所以,抱歉有错别字。
  • @SanderDeDycker 是的,这可行,但它会浪费标签上的内存,而且,就我而言,通常我可以提前知道所有工会成员都将在同一时间。

标签: c unions


【解决方案1】:

广告 1:是的,它会起作用。

ad 2:是的,它被完美地定义了。

广告 3:是的,这是合法的。

union 的整体理念是它可以容纳不同类型的元素。联合的大小将是联合中最大元素的大小。在 64 位系统上,这可能是 char * 的大小。

所以不,编译器不会假定所有元素都是 char 指针。这就是为什么你必须在你的语句中使用点符号告诉编译器你想要访问哪种类型的元素,编译器会生成访问。

但正如汤姆所说,你无法知道当前存储的是什么类型的元素;必须有一个外部原因(信息)使您知道这一点。如果知道它很重要,则应将信息存储在数据结构中,例如:

typedef struct {
    int whatisthis;
    union {
        int foo;
        char *bar;
    } u;
} int_or_str;

并将其设置为:

int_or_str example;
example.whatisthis= 1;
example.u.foo= 1;

example.whatisthis= 2;
example.u.bar= "test";

并像这样访问:

if (example.whatisthis==1) printf("%d\n", example.u.foo);
if (example.whatisthis==2) printf("%s\n", example.u.bar);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    相关资源
    最近更新 更多