如何在一个内存块中连接多个结构体?

How to Concatenate Multiple Structs within One Block of Memory?

我正在用标准 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, A, sizeof( hdrA ) );
iter += sizeof( hdrA );
memcpy( bigChunk+iter, B, sizeof( hdrB ) );
iter += sizeof( hdrB );
memcpy( bigChunk+iter, C, sizeof( hdrC ) );

我写的时候觉得很聪明,但显然有些地方不对。但我不确定是什么。其次,我认为我的 printBigChunk() 函数正确地迭代了 bigChunk。它显然多算了我需要的实际内存量。

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

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

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

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

对于第二个结构,您将把它复制到 bigChunk[8](假设没有填充),它位于 32 的 byte-offset(假设大小of 4 for int) 从内存开始。这远远超出了第二个结构的偏移量(它的 byte-offset 应该是 8)。

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