【发布时间】:2015-12-30 00:29:50
【问题描述】:
我已阅读this post。
从那,我读到了:
从 C99:6.2.7.27
指向 void 的指针应具有相同的表示和对齐方式 要求作为指向字符类型的指针。39) 类似地,指针 兼容类型的合格或不合格版本应具有 相同的表示和对齐要求。所有指向的指针 结构类型应具有相同的表示和对齐方式 互相要求。所有指向联合类型的指针都应具有 相同的表示和对齐要求。 指向其他类型的指针不需要具有相同的表示或对齐要求。 (强调我的)
我对这个问题的重要部分的解释似乎是说
如果我有:
int *a, **b;
保证注册和对齐,并且所有这些陈述都是真实的;
sizeof(a)==sizeof(*a)&&
sizeof(int *)==sizeof(b)&&
sizeof(*b)==sizeof(**b);// all essentially int pointers,
// and would be equal
但如果我有:
int *a;
float*b;
注册和对齐是不保证的。即:
sizeof(a)!=sizeof(b)&&
sizeof(float *)!=sizeof(int *)&&
sizeof(*b)!=sizeof(*a);//all pointers, but not of compatible types
//therefore not guaranteed to be equal.
我问的原因是因为this讨论,
我在其中发布了一个答案,显示了一个创建 3D 数组的函数:
int *** Create3D(int p, int c, int r)
{
int ***arr;
int x,y;
arr = calloc(p, sizeof(arr));
for(x = 0; x < p; x++)
{
arr[x] = calloc(c ,sizeof(arr));
for(y = 0; y < c; y++)
{
arr[x][y] = calloc(r, sizeof(int));
}
}
return arr;
}
就使用 sizeof() 而言,以下语句是否安全?
arr = calloc(p, sizeof(arr));
或者,即使只使用了int 类型,也应该是:
arr = calloc(p, sizeof(int **));
或:
arr = calloc(p, sizeof *arr);
问题:
给定 arr 被声明为 int ***:
对于分配内存,只要类型保持int,使用 int 指针 (int *, int **, arr, *arr, int ***) 的任何变体作为 sizeof 的参数是否有任何危险?
一种形式优于另一种形式吗? (请给出风格以外的理由)
【问题讨论】:
-
为什么
int和指针的大小应该相同?引用甚至没有提到非指针类型。而int ***是不是 3D 数组,而是指向指向int的指针的指针!注意:成为 3 星程序员并不是恭维。 -
@Olaf - 如果我建议
int和指针具有相同的大小,那是无意的。 (顺便说一下,你从我的帖子的哪个确切部分向我指出了这一点?)我真正的问题是,如果在一个类型中,使用任何形式的 int 指针来初始化内存是否安全。即,int *, int *** and int ****将为 sizeof() 产生相同的值。 -
这不是建议,而是暗示:“所有这些陈述都是正确的;
sizeof(a)==sizeof(*a)...”。您正在将苹果与橙子进行比较。指向int的指针与指向指针的指针等类型不同。*没有限定符、说明符等, -
@Olaf,请注意,在我使用的上下文中,
a是作为int ***创建的,并且仍然是int ***,而不是int。因此,有趣的是,当我比较两者的大小时,sizeof(a)==sizeof(*a)是一个真实的陈述。在大小方面,我希望a与int ***具有相同的大小。 -
除非您使用非常奇怪的非标准“C”编译器,否则
int *a只能是“指向int”的指针。因此*a是int,仅此而已。 (请注意,sizeof并不暗示类型兼容性或身份。sizeof(char [4]) == sizeof(float)` 不会产生任何关于相同对齐或表示的信息,甚至不是关于可表示范围的信息,而只是关于 -好 - 大小)。例如。sizeof(unsigned char) == sizeof(unsigned int)很可能与UCHAR_MAX == 255和UINT_MAX == 65535一起使用。