如何在一个内存块中串联多个结构?

问题描述

我正在用标准C编写程序。我有许多定义的结构,大小各异:

typedef struct innerDataStruct{
        int d1,d2;
}dataStruct;
// - - - - - - - - - - - - - -
typedef struct structA{
        dataStruct data;
}hdrA;
typedef struct structB{
        int d1,d2,d3;
}hdrB;
typedef struct structC{
        int d1;
}hdrC;

我需要分配并填充一个hdrA,hdrB和hdrC结构,然后将它们串联到一大块内存中。另外,我还需要将所有内存 分配在堆上 ,而不是本地堆栈。

(我想我可以遍历每个结构并逐个复制每个元素,但这很痛苦。此外,将来可能会修改这些结构,并且我不想重写我的结构代码的话。最好将整个结构直接复制到大块内存中。)

这是我认为可行的解决方案:

int* makeBigChunk( hdrA* A,hdrB* B,hdrC* C ){

        size_t size = sizeof( hdrA ) + sizeof( hdrB ) + sizeof( hdrC );

        int* bigChunk = malloc( size );
        bzero( bigChunk,size );

        int iter = 0;
        memcpy( bigChunk+iter,A,sizeof( hdrA ) );
        iter += sizeof( hdrA );
        memcpy( bigChunk+iter,B,sizeof( hdrB ) );
        iter += sizeof( hdrB );
        memcpy( bigChunk+iter,C,sizeof( hdrC ) );

        return bigChunk;
}

void printBigChunk( int* bc ){
        size_t size = sizeof( hdrA ) + sizeof( hdrB ) + sizeof( hdrC );
        printf("Big Chunk of Memory is :: %ld bytes:\n",size);
        int i = 0;
        for(; i < size; i++){
                printf("%d ",*(bc+i));
        }
        printf("\n");
}

int main( int argc,char **argv ){

        hdrA* AAA = malloc( sizeof(hdrA) );
        hdrB* BBB = malloc( sizeof(hdrB) );
        hdrC* CCC = malloc( sizeof(hdrC) );

        AAA->data.d1 = 1;       AAA->data.d2 = 2;
        BBB->d1 = 10;           BBB->d2 = 20;   BBB->d3 = 30;
        CCC->d1 = 100;

        int* bigChunk = makeBigChunk( AAA,BBB,CCC );
        printBigChunk( bigChunk );

        free( bigChunk );
        free( AAA );
        free( BBB );
        free( CCC );

        printf("END OF PROGRAM.\n");
        return 0;
}

我希望输出是这样:

Big Chunk of Memory is :: 6 bytes:
1 2 10 20 30 100
END OF PROGRAM.

但是实际输出不是很令人鼓舞:

Big Chunk of Memory is :: 24 bytes:
1 2 0 0 0 0 1041 0 540155953 540024880 540024880 825503793 891301920 892416052 859126069 808727840 942944816 891301944 842018868 808990772 892483616 926101557 941634361 808661305
END OF PROGRAM.

所以我猜这里有两个问题:首先,当我将每个结构memcpy() bigChunk时,我使用的是迭代系统:

int iter = 0;
memcpy( bigChunk+iter,sizeof( hdrA ) );
iter += sizeof( hdrA );
memcpy( bigChunk+iter,sizeof( hdrB ) );
iter += sizeof( hdrB );
memcpy( bigChunk+iter,sizeof( hdrC ) );

我以为那是我写的时候很聪明,但是显然有些不对。但是我不确定。其次,我认为我的printBigChunk()函数正确地遍历了bigChunk。显然,它超出了我所需的实际内存量。

有人看到我要去哪里了吗?这是一个结构填充问题还是什么?不幸的是,我不允许更改结构。谢谢!

编辑:This post是我想要做的,但不完全是。而且我无法使其适应我的代码

解决方法

请记住,对于任何指针或数组p和索引i,表达式*(p + i)等于p[i]。由此得出p + i等于&p[i]

这意味着在您的示例中,bigChunk+iter&bigChunk[iter]相同。并且由于bigChunkint *,因此编译器会将bigChunk视为 int 的数组,而不是字节的数组。>

对于第二种结构,您将其复制到{em> 32 的字节偏移量的bigChunk[8](假设没有填充)(假设4的大小为int)从内存的开头开始。这远远超出了第二个结构的偏移量(它的字节偏移量应为8)。

使用char *作为bigChunk的类型,以使其成为“字节数组”。