【问题标题】:How to Concatenate Multiple Structs within One Block of Memory?如何在一块内存中连接多个结构?
【发布时间】:2020-08-28 17:41:35
【问题描述】:

我正在使用标准 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()每个struct转换成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 是我想做的,但不完全是。而且我无法将其适应我的代码。

【问题讨论】:

  • 所以你想在sizeof(int) == 1的平台上工作?
  • 为什么不创建一个包含所有其他结构的结构并分配 那个
  • @MikeCAT 不,不一定。我正在使用 GCC 在 Linux 机器上进行编码。是什么让你这么说?
  • “大缓冲区”的目的是什么?你应该用它做什么?通过网络或串行线或类似方式传输?无论哪种方式,我真的建议您创建一个包含所有其他结构的新结构。然后很容易创建新结构的实例并将较小结构的内容复制到其中。
  • @EOF 嗯。我想我可以做到,我没有想到你的解决方案。这是你会推荐的吗?

标签: c struct malloc memcpy


【解决方案1】:

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

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

对于第二个结构,您将把它复制到bigChunk[8](假设没有填充),它的字节偏移量为32(假设int 的大小为4)从记忆的开始。这远远超出了第二个结构的偏移量(它的字节偏移量应该是8)。

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

【讨论】:

  • 有趣!因此,出于这个原因,使用 sizeof( mystruct ) 进行迭代对我来说适得其反。唔。如果我想让我的解决方案发挥作用,听起来我应该通过 num_of_elements_in_struct 或其他东西进行迭代......
  • 致所有关注此主题的人;一些程序员老兄是对的,我使用错误的大小进行迭代。当我使用调试器时,我意识到这是错误的方法。
猜你喜欢
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-13
  • 1970-01-01
  • 2021-05-18
相关资源
最近更新 更多