3

次のコードがあります

struct Info { int age; char name[5]; }
char buffer[20];
Info i;
i.age = 10;
sprintf(i.name, "Case");
strncpy(buffer+5, (char*)&i, sizeof(Info));

今、私は記録を回復したい

Info j;
strncpy((char*)&j, buffer+5, sizeof(Info));
printf("%d %s", j.age, j.name);

ただし、これは名前の空の文字列を出力します。何が間違っているのかわかりません。

4

4 に答える 4

6

コピー メカニズムには 2 つの問題があります。

  1. あなたはそれsizeof(Info)が 5 であると仮定しています。それは間違いなくそうではありません。
  2. 文字列用のを使用してstrncpyいます。 Infoは文字列ではないため、 を使用する必要がありますmemcpy

以下が機能します。

char buffer[sizeof(i)];
memcpy(buffer, &i, sizeof(i));

...

memcpy(&j, buffer, sizeof(j));

別の問題もあります。null ターミネータを考慮すると 6 文字になるため、name[5]を保持するには十分な大きさではありません。"Casey"

于 2013-02-07T15:42:13.227 に答える
4

いくつかあります:

  • バッファがオーバーフローしています。char name[5]保持できません"Casey"。ターミネータが収まりません。これにより、未定義の動作が発生します。
  • 実際には最初のフィールドが&iである を指しているのに、それが文字列へのポインタであるかのようにからコピーしています。これは確実に機能しません。structint
于 2013-02-07T15:43:07.400 に答える
0

Info変数をコピーするために memcpy() を使用する必要はありません。代入演算子を使用できます。

Info j;
j = i;
printf("%d %s", j.age, j.name);

Infoにはポインター メンバー変数が含まれていないため、これを行うことができます。したがって、代入演算子を使用すると、ディープ コピーが取得されます。デフォルトのコピー コンストラクターを使用するだけでも、同じことが起こります。

Info j(i);

また:

Info j = i;

もちろん、他の人が指摘したように、文字列ターミネータInfo::nameを含め、保存する名前を保持するのに十分な大きさにする必要があります。'\0'

于 2013-02-07T15:59:04.520 に答える
0

投稿したコードにはいくつかの問題があります。まず、"Casey" はヌルで終了する必要があることを考えると、nameフィールドが短すぎます。info

あなたが行った観察は、別の問題によるものです。のアドレスは、そのフィールドjと整列しません。nameその場所にはまだ がありint age、おそらくnameフィールドは 4 バイト後に始まりますが、これはコンパイラの裁量によるものです。

回復ageに関しては、バッファに保存されていないため、機能しません。

buffer機能するのは、それが十分に大きいと仮定してmemcpy(buffer, &i, sizeof(Info))、保存することであり、最初の2つの引数が再構築に切り替えられます。を使用すると、この構造体をメモリ内にレイアウトする方法を指定しsizeofて構造体の大きさをコンパイラに問い合わせることができるため、ここで役立ちます。Info

于 2013-02-07T15:51:18.797 に答える