Cにおけるstruct構造体の動的mallocとmemcpyのポインタ操作について


今日問題が発生しました.まずコードを貼ります.
typedef struct Gifheader      {
    char Signature[3];
    char Version[3];
    gifheader() {
        Signature[2] = '\0';
        Version[2] = '\0';
    }
}GIFHEADER;
OpenGif()
{
    QFile file(qApp->applicationDirPath()+"/gif.gif");
    if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
    {
        return;
    }
    QByteArray byte = file.readAll();
    char* p = byte.data();
    struct Gifheader* head =  (struct Gifheader*)mallGGoc(sizeof(struct Gifheader));
    memset(head,'\0',sizeof(GIFHEADER));
    memcpy(head,p,sizeof(struct Gifheader));
    qDebug("gif:[%s] version:[%s] phead = [%p] Signature:[%p] Version:[%p]"
          ,head->Signature,head->Version,head,head->Signature,head->Version);
    free(head);
}

出力結果:
gif:[GIF89a]  version:[89a] phead:[0x28f1ee8] Signature:[0x28f1ee8] Version:[0x28f1eeb]

では、これはなぜですか.まずアドレスを見てみましょう.構造体の最初のアドレスは0 x 28 f 1 ee 8で、0 x 28 f 1 eebで3バイト差があります.つまり、構造体の総サイズは6ですが、bySignatureのサイズは3バイトです.なぜ印刷されたのは[GIF 89 a]です.これは6バイトではありませんか.
元は1人で、memcpyは6バイトの空間の大きさのデータを構造体にコピーして、つまり構造体の6バイトのデータはすべてデータを充填して、1つの重要な標準があって私達は忘れることができなくて、配列を定義する時、私達は配列の最後の1つのオフセットの位置で1つの’0’を充填して配列の終わりを識別する必要があって、さもなくば配列のポインタを操作する時、オフセットして構造体に戻る可能性があります.構造体は3バイトサイズの2つの配列から構成されています.2つの配列の間に、構造体の最初のパラメータのアドレスが構造体の最初のアドレスであるため、最初の配列が印刷されると、'0'に遭遇したり、構造体の割り当てサイズの最後に終了したりします.それによって上記の状況を引き起こす
解決策:
1.構造体に配列が存在する場合、配列の特殊性を知らなければならないので、memcpyを使用して構造体ブロック全体のmemcpyを話すことはできません.cpyのソースがターゲットの構造とそっくりでない限り、このような状況は起こらないかもしれませんが、個人的には1つのcpyがより安全だと思っています.もちろん、*より良い方法があると思います.今のところ思いもよらなかった.構造体を作成するときは、できるだけ初期化構造体関数を確立し、配列が存在する場合は、配列の実際の大きさに基づいて+1を加え、'0',配列の終了を表す
次は正しいコードです.
typedef struct Gifheader      {
    char Signature[4];
    char Version[4];
    gifheader() {
        Signature[3] = '\0';
        Version[3] = '\0';
    }
}GIFHEADER;
void HImageTool::OpenGif()
{
    QFile file(qApp->applicationDirPath()+"/gif.gif");
    if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
    {
        return;
    }
    QByteArray byte = file.readAll();
    char* p = byte.data();
    GIFHEADER* head =  (GIFHEADER*)malloc(sizeof(GIFHEADER));
    memset(head,'\0',sizeof(GIFHEADER));
    memcpy(head->Signature,p,sizeof(head->Signature)-1);
    memcpy(head->Version,p+3,sizeof(head->Signature)-1);
// memcpy(head,p,sizeof(struct gifheader));
    qDebug("gif:[%s] version:[%s] phead = [%p] Signature = [%p] Version = [%p]"
           ,head->Signature,head->Version,head,head->Signature,head->Version);
    free(head);
}

結果:
gif:[GIF]  version:[89a] phead = [0x2a71ac8] bySignature = [0x2a71ac8] byVersion = [0x2a71acc]