【发布时间】:2015-09-03 11:40:01
【问题描述】:
在我发布的解决方案中,我得到了解决方案包含未定义行为的 cmets。但是,我不明白如何。发布的解决方案的基本内容是:
typedef struct {
int n;
int a[1];
} t_x;
void example(void)
{
int i;
t_x *t= malloc (sizeof(t_x) + 99*sizeof(int));
t->n= 100;
for (i=0; i < t->n; i++)
t->a[i]= i;
free(t);
}
UB 的评论集中在数组现在是有 1 个元素(如声明的那样)还是有 100 个元素(如已分配的那样)。
引用的标准部分是6.5.6(指针/int加法)和6.5.2.1(数组下标)
"6.5.6 定义了当你添加一个指针和一个整数时会发生什么。生成的指针指向数组的相应元素,如果这样的元素存在,或者指向一个元素超过末尾。否则结果未定义。"
-
“6.5.2.1 定义了
a[n]在a+n方面的含义。因此,如果 a 至少没有n+1元素,则不能说a[n]。”
使用这两个引号,评论者似乎暗示元素 a[99] 将不存在,但是,查看内存布局它显然存在:
请帮助我了解这是否/为什么是 UB 以及我可能期望的 UB 类型。
【问题讨论】:
-
答案可能取决于您正在处理的 C 标准(C89、C99、C11)。在 C99 及更高版本中,您的代码闻起来很糟糕,因为您应该使用 flexible array member,但我猜它不是 UB
-
它是 UB,至少按照 C99 之前的标准,访问
a越界。它的类型为int [1];a[0]以上的任何访问权限都是未定义的。