C中的灵活结构

时间:2012-12-05 20:03:35

标签: c arrays pointers

我看到了一些代码如下:

struct Hello
{
   int age;
   int time;
   int data[1];
};

struct Element
{
   int a;
   int b;
};

struct Element element_[5] = (/* Initiate the array */);
struct Hello* hello = (struct Hello*)malloc(sizeof(Element)*5);
struct Element * element_p = NULL;

element_p = (struct Element *)hello->data;

for(int i = 0; i<5; i++)
{
   memcpy(element_p, &element_[i], sizeof(struct Element));
}

这一行:element_p = (struct Element *)hello->data;,为什么我们需要投射hello->data to (struct Element *)?这是否意味着element_p指针上的操作与hello->data的操作相同?并且此行是否会将struct Element element_[5]的每个元素的地址填充到hello->data的每个元素中?

2 个答案:

答案 0 :(得分:8)

这很糟糕可怕 C ++。需要演员,因为hello->data实际上是int[],所以不能直接转换为{{ 1}}。

此外,它是未定义的行为,因为Element*未初始化,但您取消引用它(通过hello)。

答案 1 :(得分:0)

element_p必须是struct Element的指针,但hello->dataint data[1],因此您需要演员。假设你初始化hello你“强制”element_p是一个指向单个整数所在内存区域的指针,因为实际上hello->data将指向第一个且唯一的整数“包含“在数组hello->data[]中。由于struct Element“包含”2个整数,element_p->a应该访问hello->data[0],但element_p->b会尝试访问hello->data[1],这超出了2*sizeof(int)阵列。

for循环将从每个初始化结构element_中取出的struct Element(很可能是element_p)的大小的数据复制到element_p指向的数据中,我们已经说过了,因为缺少部分(见下面的黑客),只有1个空间。由于hack保持不变,您将覆盖该内存,并且只有最后复制的“struct”才能存活。

正如您向我们展示的那样,它看起来像是撞车的好方法。无论如何,如果element_p Joe在评论中进行了讨论,struct Element将指向其他几个“整数”的第一个int。由于整数只是记忆,它们足以容纳element_p[0]结构,你可以使用element_p[1]第一个, hello = malloc(sizeof (*hello) + sizeof (struct Element) * 6); 第二个,以此类推。可能像

element_p = (struct Element *)hello->data

或类似的。现在,可以使用element_p

无论如何,for循环继续在同一区域上写,Element需要提前1(1个整个结构element_p+i),以便每次填充不同的区域({{1} } shoudl go)。