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 Elementhello->dataint data[1]であるため、キャストが必要です。hello「force」を初期化して、単一の整数が存在するメモリ領域へのポインタであると仮定しますelement_p。これは、実際hello->dataには、配列に「含まれる」最初で唯一の整数を指すためhello->data[]です。struct Element2つの整数を「含む」ので、にelement_p->aアクセスする必要がありますが、配列の範囲外にあるにアクセスしようとします。hello->data[0]element_p->bhello->data[1]

2*sizeof(int)forループは、初期化された各構造体から取得された構造体要素のサイズのデータ​​(非常に可能性が高い)を、前述のように、欠落している部分(以下のハックを参照)のために、そのelement_ポイントにコピーします。element_pたった1intで。同じままなのでelement_p、そのメモリを上書きし、最後にコピーされた「構造体」のみが存続します。

あなたが私たちに示したように、それはクラッシュの良いレシピのように見えます。とにかく、hack ジョーがコメントで話している場合は、element_p他のいくつかの「int」の最初のintを指します。intはメモリに他ならないので、1番目、2番目などでstruct Elementアクセスできる構造体を収容するのに十分である可能性があります。おそらく次のようなものelement_p[0]element_p[1]

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

または同様に。今、element_p = (struct Element *)hello->data使用することができます。

とにかく、forループは同じ領域に書き込みを続け、異なる領域(shoudl go)を毎回埋めるためにelement_p、1(1つの構造体全体)進む必要があります。Elementelement_p+i

于 2012-12-05T20:39:25.577 に答える