1

以下に書かれているコードを見ました。

typedef struct abc {
    int a;
    char b;
    float c;
} abc;

int main()
{
  abc *ab;
  int *i;
  i = (int*)malloc(sizeof(int));
  *i = 0;
  ab = (abc*) i;

  return 0;
}

最後から 2 番目の行ab = (abc*) i;で、コードは何をしようとしていますか?

の値を設定したい場合、次のab->a方法ではなく、なぜこの方法で行われるのですか?

ab->a = (int)i;

ab = (abc*) i;の値を更新する場合ab->a、他の 2 つの構造体メンバーを排他的に初期化せずにどのように初期化しますか?

4

5 に答える 5

4

では、他の 2 つの構造体メンバーを排他的に初期化せずにどのように初期化するのでしょうか?

彼らはしません。

とは、 のインスタンスを表すのに十分なサイズのメモリのチャンクを表していないため、ガベージ値を取得することになりab->bます。ab->ciabc

ab->aは 0 に等しいです。これは、 を実行したときに、 を指すメモリ位置に*i = 0値を保存したためです。と同じメモリ位置を指定した場合、メモリへの書き込みは行われず、データの位置を変更しただけです。0iabci

以前は指さ0れた位置に 4 バイトで格納されていたため、たまたま 4 バイトを使用し、たまたま構造体の最初のメンバーでもあったため、0 に等しくなります。iint ab::aab->a

メモリ内で、インスタンスの位置を基準にして、構造体は次のように並べられます。

 ____ ____ ____ ____    ____    ____ ____ ____ ____
| 00 | 01 | 02 | 03 |  | 04 |  | 05 | 06 | 07 | 08 |
|____|____|____|____|  |____|  |____|____|____|____|
        int a          char b         float c

これで問題が解決することを願っています。


上記の表現で示したように、構造体が完全にパックされているとは限りません。順序は維持されますが、連続するメンバー間のスペースが常に 0 メモリ アドレス単位になるとは限りません。アライメントを読んでください。

于 2013-03-29T07:36:31.557 に答える
3

この行は、 type のポインター変数を typeにab = (abc*) i;キャストし、その代入をポインター variable に行っています。これは確かに、構造体のデータ メンバーを初期化する方法ではありません。特に、 に十分なスペースしか割り当てられておらず、 よりもかなり多くのスペースを占有する構造体を使用しているためです。iint*abc*abintint

結局のところ、それは合法的なコードですが、非常に恐ろしいものです。int aが指すアドレスにデータメンバーが格納されていることを保証できるかどうかさえわかりませんab。実装に依存していると言いたいのですが、他の誰かがそれを解決してくれるかもしれません。

于 2013-03-29T07:38:01.820 に答える
2

その最後から 2 番目の行により、 から(int *)への変換が行われ(abc *)、その結果が ab に代入されます。古いポイント先の型は新しいポイント先の型よりもサイズが小さいため、これはあまり良いコード行ではありません。この変換の結果を使用しようとすると、未定義の動作になります。のままにしておく(int *)か、変換するプレフィックス構造体を宣言する方がはるかに良い考えです。

*inabc *は、型が「abc へのポインター」であることを示します。abオブジェクトを指すように指示するまで、オブジェクトを指しませんabc何かを指すようにab = /* something */代入します。この例では、意味があります。abab = malloc(sizeof *ab);

これはばかげています: i = (int*)malloc(sizeof(int));. malloc の戻り値をキャストする必要はありません。これの唯一の正当な理由は、このコードの作成者が#include <stdlib.h>. 戻り値をキャストするのではなく、そのライブラリを含めることをお勧めします。私のアドバイスは無視してかまいませんが、このページを読むまでは奇妙なエラーについて質問しないでください。

于 2013-03-29T07:43:54.807 に答える
1

abc *ab;ab は struct abc 型のポインタです。 int *i;によって返される int へのポインタです。malloc

その値は次を使用して設定されます*i = 0;

ab = (abc*) i;

この行は、malloc によって割り当てられた場所のアドレスを ab に割り当てています。に型キャストiすることにより、ab がa に値を割り当てない(abc*)サイズのメモリ チャンクを読み取るために使用されることが示されます。auに値を割り当てるにはstruct abc ab = (abc*) i; ab->a = 5;

すでに存在する値はガベージ値です (デフォルトのランダム値)

于 2013-03-29T07:39:04.343 に答える
-2
ab = (abc*) i; updates the value of ab->a

構造体のレイアウトを見てみると、intはintが最初のメンバーなので0で初期化されるので、ansはyes!私はVCで試してみましたが、0で初期化しましたが、これはトリッキーです.構造体の場合、メンバーの変更順序が変更された場合、グラベージが発生します!

メモリリークもあり、malloc で割り当てられたメモリは決して解放されません!

于 2013-03-29T07:40:39.350 に答える