C-未命名结构的柔性阵列成员



考虑以下示例:

typedef struct test_flex_arr{
    size_t sz;
    struct {
        int i;
        const char *path;
    } info[];
} tfa;
int main(void){
    size_t sz = 100;
    tfa *ptr = malloc(sizeof *ptr + sizeof (*((tfa*) NULL)).info[sz]);
    ptr->info[99].i = 10;
    printf("%dn", ptr->info[99].i); //prints 10
}

演示

我希望这个程序崩溃,但运行良好。如指定的6.5.3.4(p2)

sizeof操作员产生其操作数的大小(以字节为单位(, 可能是一种类型的表达式或括号的名称。大小是 根据操作数的类型确定。结果是整数。如果 操作数的类型是可变长度阵列类型,操作数 评估;否则,未评估操作数,结果 是整数常数

sizeof ((*((tfa*) NULL)).info)[sz]的操作数类型是可变长度阵列,因此应评估操作数。但是对操作数的评估是指我希望导致崩溃的NULL

代码的行为定义很好?

(*((tfa*) NULL)).info[sz]不是可变长度类型,因为 (*((tfa*) NULL)).info不是类型。

因此,它是一种普通表达式,指的是数组(*((tfa*) NULL)).infosz元素。根据引用的规范,未评估这一点,因此它表示NULL不会引起不确定的行为。它只是返回数组元素的大小,该元素的大小不取决于数组或索引的位置。这就是为什么它在没有警告的情况下编译并且不会崩溃的原因。

,但这不会产生所需的结果。您只能获得数组中一个元素的大小,而不是实际需要为空间分配空间的sz元素。您需要将元素的大小乘以元素的数量。所以使用

tfa *ptr = malloc(sizeof *ptr + sz * sizeof ptr->info[0]);

最新更新