0

我看到一些代码如下:

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_pwill指针的操作对hello->data? 这一行是否会将每个元素的地址填充struct Element element_[5]到 的每个元素hello->data

4

2 回答 2

8

这是可怕的可怕的C++。演员表是必需的,因为hello->data实际上是一个int[],所以不能直接转换为一个Element*

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

于 2012-12-05T20:06:50.987 回答
0

element_p必须是指向struct Elementbut hello->datais的指针int 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 循环将从每个已初始化的 struct 中获取的 struct Element 大小的数据(很可能)复制element_到所指向的数据element_p中,正如我们所说,并且由于缺少部分(参见下面的 hack),有空间只需 1 个整数。由于element_p保持不变,您将覆盖该内存,并且只有最后一个复制的“结构”将继续存在。

正如您向我们展示的那样,它看起来像是一个很好的崩溃方法。无论如何,如果hack 乔在评论中谈论的内容到位,element_p将指向其他几个“整数”中的第一个整数。由于 int 只不过是内存,因此它们足以容纳struct Element您可以使用element_p[0]第一个、element_p[1]第二个等访问的结构。可能像

  hello = malloc(sizeof (*hello) + sizeof (struct Element) * 6);

或类似的。现在,element_p = (struct Element *)hello->data可以使用了。

无论如何,for循环继续写入同一区域,element_p需要提前1(1个整个结构Element)以便每次填充不同的区域(element_p+i应该去)。

于 2012-12-05T20:39:25.577 回答