在我发布的解决方案中,我得到的评论是解决方案包含未定义的行为。但是,我不知道怎么做。发布的解决方案的基础是:
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至少a[n]
,则无法说n+1
} elements。“
对于这两个引号,评论者似乎暗示元素a[99]
不存在,但是,看看内存布局显然存在:
请帮助我理解是否/为什么这是UB以及我可能期望的UB类型。
答案 0 :(得分:4)
这是前C99代码中非常流行的技巧。它适用于许多实现,但严格来说并不合法(因此不可移植)。该标准没有说明t_x
的结构如何在记忆中对齐。有关详细信息,请参阅C FAQ。
C99引入了灵活的长度阵列,这是这种问题的首选。
答案 1 :(得分:0)
好的,问题是,您要为代码中定义的表分配内存。在编写时,此表的大小始终为1,因此您可以在其中存储一个int类型的对象。
如果你想为a动态分配内存,那么你应该:
typedef struct {
int n;
int* a;
} t_x;
然后
t_x someStruct;
someStruct.a=(int*)malloc(numberOfElements*sizeof(int));