#include <cstring>
#include <cstdio>
#include <cstdlib>
struct Block {
int32_t size;
u_int8_t data[0];
};
int main(int argc, char **argv) {
Block block;
Block *ptr = █
u_int8_t data_buffer[] = {1, 3, 0, 1, 3, 4, 5, 5, 6, 2, 2, 3};
void *sdata = (void *)data_buffer;
void *ndata = (void*)ptr->data;
printf("data ptr: %p\n", ptr->data); // 0x7ffe53275340
printf("ndata: %p\n", ndata); // 0x7ffe53275340
memcpy((void*)ndata, &data_buffer, sizeof(void*));
printf("ndata: %p\n", ndata); // 0x505040301000301
printf("*(&data_buffer): %p\n", *(&data_buffer)); // 0x7ffe53275330
printf("data ptr: %p\n", ptr->data); // 0x7ffe53275340
for(int i{0}; i<12; i++) {
printf("%d ", (((u_int8_t*)(ptr->data))[i]));
}
printf("\n");
return 0;
}
代码块如上,
我很困惑,在memcpy函数之后,为什么ndata会变成0x505040301000301,一个如此奇怪的值?
我用谷歌搜索了灵活数组,但找不到确切的这种例子。 任何帮助将不胜感激。
具有灵活数组成员的结构体的大小不包括该成员的空间。 因此,如果您在堆栈上声明这样的结构,您实际上无法访问这些元素,因为它们不存在。 你正在做的是未定义的行为,因为你访问的内存超出了对象的边界。
您需要做的是声明一个指向该结构的指针,并为该结构以及所需数量的成员分配空间。
u_int8_t data_buffer[] = {1, 3, 0, 1, 3, 4, 5, 5, 6, 2, 2, 3};
struct Block *ptr = malloc(sizeof(struct Block) * sizeof(data_buffer));
还有:
0
作为数组大小是 GCC 扩展。 您应该将尺寸留空,这是符合 C 标准的方法。stdio.h
而不是 cstdio
),在声明结构时使用 struct
关键字,并编译为 C 程序。