1 char s[0] 和 char * a比较
void zero_arr_ptr(void)
{
char s[0] = {0};
char * a = NULL;
//由下面的结果可以得出:
//零长度数组所占内存空间为0,指针占内存空间为4
//s和&s的结果一样,a获取a指向的地址,&a获取去自身的地址;
printf("zero_arr_ptr:\n")
printf("sizeof(s)=%d,sizeof(a)=%d\n",sizeof(s),sizeof(a));
printf("s = %x,a = %x\n",s,a);
printf("&s = %x,&a = %x\n",&s,&a);
}
2 关于零长度数组
首先,我们要知道,0长度的数组在ISO C和C++的规格说明书中是不允许的。这也就是为什么在VC++2012下编译你会得到一个警告:“arning C4200: 使用了非标准扩展 : 结构/联合中的零大小数组”。
那么为什么gcc可以通过而连一个警告都没有?那是因为gcc 为了预先支持C99的这种玩法,所以,让“零长度数组”这种玩法合法了。关于GCC对于这个事的文档在这里:“Arrays of Length Zero”,文档中给了一个例子(自己改了一下):
#include <stdlib.h>
#include <string.h>
struct line
{
int length;
char contents[0]; // C99的玩法是:char contents[]; 没有指定数组长度
};
int main()
{
int this_length=10;
struct line *thisline = (struct line *)malloc(sizeof (struct line) + this_length);
thisline->length = this_length;
memset(thisline->contents, 'a', this_length);
return 0;
}
题外话:这里也可以把contents改为指针,实现相应的功能。
需要注意三点区别:
- 如果结构体指针和结构体成员指针指向的内存不是同时申请,则有可能不连续。
- 如果依然用上面的申请内存方式,则还要给结构体中的指针成员初始化为指向自身的下一个地址。
- 申请的空间比零长度数组要多4个字节;