Geo*_*org 0 c struct flexible-array-member
我是C的新手,我在使用结构时遇到了麻烦.我有以下代码:
typedef struct uint8array {
uint8 len;
uint8 data[];
} uint8array;
int compare_uint8array(uint8array* arr1, uint8array* arr2) {
printf("%i %i\n data: %i, %i\n", arr1->len, arr2->len, arr1->data[0], arr2->data[0]);
if (arr1->len != arr2->len) return 1;
return 0;
}
int compuint8ArrayTest() {
printf("--compuint8ArrayTest--\n");
uint8array arr1;
arr1.len = 2;
arr1.data[0] = 3;
arr1.data[1] = 5;
uint8array arr2;
arr2.len = 4;
arr2.data[0] = 3;
arr2.data[1] = 5;
arr2.data[2] = 7;
arr2.data[3] = 1;
assert(compare_uint8array(&arr1, &arr2) != 0);
}
Run Code Online (Sandbox Code Playgroud)
现在这个程序的输出是:
--compuint8ArrayTest--
3 4
data: 5, 3
Run Code Online (Sandbox Code Playgroud)
为什么值不是我初始化它们的值?我在这里错过了什么?
在您的情况下,uint8 data[];是一个灵活的阵列成员.您需要先分配内存data才能实际访问它.
在您的代码中,您正在尝试访问无效的内存位置,从而导致未定义的行为.
引用C11,章节§6.7.2.1(强调我的)
作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型; 这被称为灵活的阵列成员.在大多数情况下,将忽略灵活数组成员.特别地,结构的尺寸好像省略了柔性阵列构件,除了它可以具有比省略意味着更多的拖尾填充.但是,当一个.(或 - >)运算符有一个左操作数,它是一个带有灵活数组成员的结构(一个指针),右操作数命名该成员,它的行为就好像该成员被最长的数组替换(具有相同的元素类型) )不会使结构大于被访问的对象; 数组的偏移量应保持为灵活数组成员的偏移量,即使这与替换数组的偏移量不同.如果此数组没有元素,则其行为就好像它有一个元素,但如果尝试访问该元素或生成一个超过它的指针,则行为是未定义的.
正确的用法示例也可以在章节§6.7.2.1中找到
例2声明后:
Run Code Online (Sandbox Code Playgroud)struct s { int n; double d[]; };该结构
struct s具有灵活的阵列成员d.使用它的典型方法是:Run Code Online (Sandbox Code Playgroud)int m = /* some value */; struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));并且假设调用
malloc成功,p对于大多数目的,行为所指向的对象就像p被声明为:Run Code Online (Sandbox Code Playgroud)struct { int n; double d[m]; } *p;