2012-05-10 9 views
0

私は以下の2つの構造を持っています。私はd, e, fsourceからdestinationまでmemcpyoffsetofを使ってコピーする必要があります。これどうやってするの?コンパイラは二つの構造は異なるパッドに許可されているので'offsetof'を使用して異なる構造間で 'memcpy'を実行するにはどうすればよいですか?

struct source 
{ 
    int a; 
    int b; 
    int c; 
    int d; 
    int e; 
    int f; 
}; 

struct destination 
{ 
    int d; 
    int e; 
    int f; 
}; 
+3

は、あなたがこれまでにやっている私たちを表示します。さもなければ、人々はあなたが彼らにあなたの宿題をさせようとしていると思われるでしょう。 – janneb

+0

なぜmemcpyを使いたいのですか?これはstruct packingについての宿題ですか? –

+0

これは宿題の場合、宿題タグを追加しますか?ありがとう。 – octopusgrabbus

答えて

4

一般的に、あなたは確実に、memcpyを使用してそれを行うことはできません。したがって、部分コピーを実行する最も安全な方法は、3つのフィールドを個別に割り当てることです。ので、ゼロであることが保証されて

struct source s {1,2,3,4,5,6}; 
struct destination d = {100, 200, 300}; 
memcpy(&d, ((char*)(&s))+offsetof(struct source,d), offsetof(struct source,f)-offsetof(struct source,d)+sizeof(int)); 

destinationdのオフセット:コンパイラは、あなたの特定のケースで異なる整列要件を持つメンバー間にパディングを挿入しますので、

ただし、このようなmemcpyを使用することができますそれは構造の最初のメンバーです。 de、およびfは同じアライメント要件を持っているので、パディングがある場合は、struct destinationではそれを後にし、struct sourceではそれらの前後になります。

オフセットはバイト単位で表されるため、char*にキャストする必要があります。

表現

offsetof(struct source,f)-offsetof(struct source,d)+sizeof(int) 

df、までの間のランの長さです。 sizeof(struct destination)を使用することは、struct sourceに存在しない末尾にパディングがあり、割り当てられたメモリを超えて読み込みが発生する可能性があるため、安全ではありません。

+1

割り当てによって必要とされるが、どちらの場合も、 'offsetof'の使用は非生産的である。 'offsetof(struct source、f)-offsetof(struct source、d) 'は'(char()) '+ offsetof(struct source、d) *)&s.f - (char *)&s.d'。 –

+0

@SteveJessop絶対に! '&s.d'は' offsetof'を使うよりはるかにクリーンです。 – dasblinkenlight

+0

私はマーカーが正しく実行するためのパスを与えるかどうか疑問に思っていますが、どこかで 'offsetof'を投げても無害です;-)通常は' offsetof'はあなたが動作させる構造体のインスタンスを持たないか例えばあなたの構造体がファイルフォーマットやインターネットプロトコルのようなbyte-for-byteのいくつかの仕様に合っていることを静的にアサートする)、そうでなければフィールドの名前を抽象化したい(例えば、各オブジェクトは訪問された)。 –

0

"dasblinkenlight"と言えば、これは可能なパディングのためにmemcpyによって確実に行うことはできません。あなたはまた、送信元と送信先の構造にint型のポインタを使用し、先のポインタに値を代入し、送信元と宛先の両方のint型のポインタを減少させることができ、このシナリオでは

struct Part1 
{ 
    int a; 
    int b; 
    int c; 
}; 

struct Part2 
{ 
    int d; 
    int e; 
    int f; 
}; 

struct source 
{ 
    struct Part1 p1; 
    struct Part2 p2; 
}; 

struct destination 
{ 
    struct Part2 p2; 
}; 

// ... 
src.p2 = dst.p2; 
+4

Cに継承がありません。 – interjay

+0

@interjay:継承を削除しました。今はメンバーです(バイナリレベルで同じです) – valdo

0

: ただし、このような何かを行うことができます。

次のようにコードのスニペットがある: -

struct destination * my_copy (struct source *pfSrc, struct destination *pfDes) 
{ 
    int *pSrc = (int *)pfSrc; 
    int *pDes = (int *)pfDes; 
    pSrc += (sizeof (struct source)/sizeof (int)) - 1; 
    pDes += (sizeof (struct destination)/sizeof (int)) - 1; 
    do 
    { 
    *pDes = *pSrc; 
    pSrc--; 
    }while (pDes-- != (int *)pfDes); 
return pfDes; 
} 
関連する問題