联合体。。。
结构体。。。
对于宏的理解
6-1到6-2的练习实例
unset 很巧妙。只是把type 置为了0。而不是真正的抹掉了内存。下次用的时候根据type做判断,直接覆盖。这样大大的节约了性能。
gdb调试查看,值的存储位置
gdb 调试 packet array 变成了hash array
Packed Array 和Hash Array。
如果能用到Packed Array 就尽量使用Packed Array。节省内存。
多出1MB的内存用到哪里了?
hashtable的巧妙设计
nTableMask:用来计算最终落到哪个桶里边的一个值。
arData 数组中的每个元素都是一个bucket。Bucket结构体元素如下。
zval 是key-value的value
zend_ulong h 是hash算法算出来的hash值
*key 是key-value的key
nNumUsed代表了有多少bucket 被使用了。
nNumofElements是跟nNumofElements是有区别的,比如unset 掉一个数组中的一个元素,nNumUsed并不会减少。nNumofElements会减少,nNumOfElements是真正有意义的值,不包括unset掉的值。
nTableSize 是bucket大小。
nInternalPointer内部指针。
nNextFreeElement :有时候并不写key就赋值一个value。通过这个nNextFreeElement知道了应该放到哪个位置。
pDestructor :用来析构用的。
字符串的写时复制
这种字符串的实现是二进制安全的。
什么是非二进制安全?字符串以\0结尾,如果字符串中有\0那么就会被截断。
什么是二进制安全呢?可以字符串len获取字符串的内容,即便字符串中有\0也不会因此而截断。
柔性数组
变量,简单的图示
gdb 查看底层变量的存储方式
zend_uchar type 这个用一个字节表示变量的类型。
zend_value每一项的字段解释。
zval 的结构体占用大小
判断大小端的demo
结构体内存 8字节对齐,联合体复用内存
char a 1
int b 4
long 8
viod* 8
int e 4
char* f 8
union_u{...}
//这里是联合体 联合体的大小为8字节 内容和结构体一样
但是不同之处它的变量是复用的 反复在这8字节存储
stuct_s{ //这里是结构体 结构体的总大小是40字节
在内存里是按字节对齐存放的 且小于4字节 的以4个字节的位置放置 单行大小为8字节对齐 整体结构体以8个字节对齐
char a; //1字节
int b;//4字节
long c;//8字节
void* d;//8字节
int e;//4字节
char*f;//8字节
}
32312313123213213
整型和浮点型