在看侯捷的<深度探索c++对象模型>时有一段提到c语言中的一个技巧,就是把单一元素的数组放在一个struct的尾端,于是每个struct objects可以拥有可变大小的数组:
struct mumble{
/*stuff */
char pc[1];
}
//从档案或标准输入中取得一个字符串,然后为struct本身和该字符串配置足够的内存
struct mumber *pmumb1 =(struct mumble*)malloc(sizeof(struct mumble)+strlen(string)+1;
strcpy(pmumbl1->pc, string);
我在网上看了几篇文章,这中用法貌似在socket中需要发送不定长的包时常用.他们主要和下面这种方法比较:
struct mumble{
/*stuff*/
char* pc;
}
把pc定义为指针后就需要动态分配数组,这样数组空间和mumble就不是连续的了. 貌似还有其他的好处,不列举了. 我比较疑惑的有两点:
- 一般都把pc声明为长度为0的数组char pc[0],侯捷的书里把它声明为长度为1的数组char pc[1],这两者有什么区别吗? 既然0,1都可以,我就试着声明为其他长度比如2,3,发现也没问题.和声明为0,1相比,差别仅仅在于节省了空间吗?
- 为mumble申请了一大块内存后,pc就指向了一块内存,但是声明时它是0长度或是长度为1的,访问pc[2],pc[3]时为什么没有越界?
多谢了
char pc[1]
是为了兼容性。有些编译器不支持长度为0的数组。在C语言里,
越界
本身是个"伪概念",更明确地应该是说访问的空间是否真实合法有效。声明与实际访问没有任何关系,举个栗子,下面这段代码里p在声明/定义的时候甚至连0或1都没有,那后面的访问是否越界
了?