这是使用数组未定义的行为吗?

时间:2015-09-03 11:40:02

标签: c arrays

在我发布的解决方案中,我得到的评论是解决方案包含未定义的行为。但是,我不知道怎么做。发布的解决方案的基础是:

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]不存在,但是,看看内存布局显然存在:

enter image description here

请帮助我理解是否/为什么这是UB以及我可能期望的UB类型。

2 个答案:

答案 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));