我有一个包含灵活成员数组的结构:
typedef struct bar {
uint8_t bar_a;
uint16_t bar_b;
} bar_t;
typedef struct foo {
uint16_t foo_a;
uint_8_t n_bars;
bar_t *bars[];
} foo_t;
我尝试使用foo
和bar
作为数据结构将数据复制到uint8_t buffer[50]
。
#define NUMBER_OF_BARS 1;
static uint8_t buffer[50];
static foo_t *
copy_to_buf(void *buf)
{
int i;
foo_t *foo = (foo_t *)buf;
bar_t bar;
/* Set foo_a */
foo->foo_a = 1;
foo->n_bars = NUMBER_OF_BARS;
/* Set bars */
for(i=0; i < foo->n_bars; i++) {
bar.bar_a = 0xFF;
bar.bar_b = 1234;
memcpy(&foo->bars[i], &bar, sizeof(bar_t));
}
return foo;
}
int main()
{
int i;
foo_t *foo = copy_to_buf(&buffer);
printf("foo ... [%p %p %p %p]\n",
&foo, &foo->foo_a, &foo->n_bars &foo->bars);
for(i=0; i < foo->n_bars; i++) {
printf("bar ... [%p %p %p]\n",
&foo->bars[i], &foo->bars[i]->bar_a, &foo->bars[i]->bar_b);
}
return 0;
}
现在我希望这可以打印以下内容(即一块连续的内存块):
foo ... [0x1f92 0x1f92 0x1f94 0x1f95]
bar ... [0x1f95 0x1f95 0x1f96]
相反,我得到以下内容:
foo ... [0x1f92 0x1f92 0x1f94 0x1f95]
bar ... [0x1f95 0x0 0x1]
我做错了什么?
答案 0 :(得分:2)
由于foo.bars
是一个指针数组,您需要为它们指向的对象分配内存,然后复制到该内存。
static foo_t *
copy_to_buf(void *buf)
{
int i;
foo_t *foo = (foo_t *)buf;
bar_t bar;
/* Set foo_a */
foo->foo_a = 1;
foo->n_bars = NUMBER_OF_BARS;
/* Set bars */
for(i=0; i < foo->n_bars; i++) {
bar.bar_a = 0xFF;
bar.bar_b = 1234;
foo->bars[i] = malloc(sizeof(bar_t));
memcpy(foo->bars[i], &bar, sizeof(bar_t));
}
return foo;
}
或者你可以将它声明为结构数组而不是指针。
typedef struct foo {
uint16_t foo_a;
uint_8_t n_bars;
bar_t bars[];
} foo_t;
并更改您在main()
int main()
{
int i;
foo_t *foo = copy_to_buf(&buffer);
printf("foo ... [%p %p %p %p]\n",
&foo, &foo->foo_a, &foo->n_bars &foo->bars);
for(i=0; i < foo->n_bars; i++) {
printf("bar ... [%p %p %p]\n",
&foo->bars[i], &foo->bars[i].bar_a, &foo->bars[i].bar_b);
}
return 0;
}