在学习PHP的字符串时,我们知道存储在zend_string中,来看一下
struct _zend_string {zend_refcounted_h gc;zend_ulong h; / hash value /size_t len;char val[1];};
这里 char val[1] 只占一个字节内存,我们可能会感到奇怪,长度为1的数组如何存的下大于1长度的字符串呢,实在这里利用了C的柔性数组。
柔性数组可以认为是边长数组,只能涌如今构造体的末了一个成员位置,它可以自动扩容。

上面是柔性数组的一种形式,柔性数组还有一种形式 char val[], 这是由于遵照的标准不一样。
来看例子
int main(){ / 柔性数组可以理解为非定长数组,实际的长度是动态的 1、必须要声明在构造体的结尾 2、不占用内存 3、利用内存缓冲区 4、自动扩容 / struct User { int age; int stuID; char address[]; // 构造体结尾 }; // 8 两个int 4 + 4 // char address[] 不占内存 printf("size of user %lu \n", sizeof(struct User)); struct User jack; // address赋值 jack.address[0] = 'b'; jack.address[1] = 'e'; jack.address[2] = 'i'; jack.address[3] = 'j'; jack.address[4] = 'i'; jack.address[5] = 'n'; jack.address[6] = 'g'; jack.stuID = 1; // 8 解释 address并没有占用内存 printf("size of jack %lu \n", sizeof(jack)); // beijing printf("address is %s \n", jack.address); printf("下面利用指针来 \n"); struct Stu { int age; int stdID; char address; }; // 16 int + int + char的指针 4+4+8 // 明显指针是占用内存的 printf("size of std %lu \n", sizeof(struct Stu)); char myAddress[7]; myAddress[0] = 't'; myAddress[1] = 'i'; myAddress[2] = 'a'; myAddress[3] = 'n'; myAddress[4] = 'j'; myAddress[5] = 'i'; myAddress[6] = 'n'; struct Stu rose; rose.address = myAddress; rose.stdID = 2; printf("size of rose %lu \n", sizeof(rose)); printf("address is %p \n", rose.address); printf("address[0] is %c \n", (rose.address)); printf("address[1] is %c \n", (rose.address+1)); printf("柔性数组的第二种办法 \n"); struct zend_string { int refcount; int len; char val[1]; }; // 12 字节 int +int + char内存对齐 43 printf("size of zend_string %lu \n", sizeof(struct zend_string)); struct zend_string str1; str1.len = 5; str1.val[0] = 'h'; str1.val[1] = 'e'; str1.val[2] = 'l'; str1.val[3] = 'l'; str1.val[4] = 'o'; // 12 val赋值之后仍旧内存空间没有变革 printf("size of zend_string %lu \n", sizeof(str1)); // hello printf("size of zend_string.val %s \n", str1.val); / struct _zend_string { zend_refcounted_h gc; zend_ulong h; size_t len; char val[1]; }; / / val[] 与 val[1] 两种实现办法不太一样,由于标准不一样 c99 标准中许可 char val[] 这种定义作为柔性(不定长)数组涌现,他不占用内存空间 c99之前只支持 char val[1]这种格式,占用1个字节 / return 0;}
总结:
柔性数组可以理解为非定长数组,实际的长度是动态的
必须要声明在构造体的结尾不占用内存利用内存缓冲区自动扩容